contextsynapse 1.0.0__py3-none-any.whl

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 (776) hide show
  1. contextsynapse/__init__.py +107 -0
  2. contextsynapse/__main__.py +9 -0
  3. contextsynapse/a2a/__init__.py +28 -0
  4. contextsynapse/a2a/client.py +120 -0
  5. contextsynapse/a2a/discovery.py +128 -0
  6. contextsynapse/a2a/handlers.py +164 -0
  7. contextsynapse/a2a/models.py +246 -0
  8. contextsynapse/a2a/streaming.py +92 -0
  9. contextsynapse/a2a/task_manager.py +275 -0
  10. contextsynapse/adapters/__init__.py +98 -0
  11. contextsynapse/adapters/_base.py +298 -0
  12. contextsynapse/adapters/autogen/__init__.py +4 -0
  13. contextsynapse/adapters/autogen/tools.py +34 -0
  14. contextsynapse/adapters/crewai/__init__.py +4 -0
  15. contextsynapse/adapters/crewai/tools.py +63 -0
  16. contextsynapse/adapters/langchain/__init__.py +19 -0
  17. contextsynapse/adapters/langchain/message_history.py +17 -0
  18. contextsynapse/adapters/langchain/retriever.py +158 -0
  19. contextsynapse/adapters/langchain/tools.py +43 -0
  20. contextsynapse/adapters/langgraph/__init__.py +21 -0
  21. contextsynapse/adapters/langgraph/checkpoint.py +223 -0
  22. contextsynapse/adapters/langgraph/context_tools.py +341 -0
  23. contextsynapse/adapters/langgraph/message_history.py +138 -0
  24. contextsynapse/adapters/langgraph/tools.py +43 -0
  25. contextsynapse/adapters/llamaindex/__init__.py +4 -0
  26. contextsynapse/adapters/llamaindex/tools.py +64 -0
  27. contextsynapse/adapters/openai/__init__.py +24 -0
  28. contextsynapse/adapters/openai/tools.py +206 -0
  29. contextsynapse/adapters/pydantic_ai/__init__.py +4 -0
  30. contextsynapse/adapters/pydantic_ai/tools.py +36 -0
  31. contextsynapse/adapters/swarm/__init__.py +4 -0
  32. contextsynapse/adapters/swarm/tools.py +44 -0
  33. contextsynapse/agents/__init__.py +6 -0
  34. contextsynapse/agents/auto_capture.py +80 -0
  35. contextsynapse/agents/dispatcher.py +299 -0
  36. contextsynapse/agents/notifications.py +112 -0
  37. contextsynapse/aiql/__init__.py +71 -0
  38. contextsynapse/aiql/cache.py +341 -0
  39. contextsynapse/aiql/compiler/__init__.py +62 -0
  40. contextsynapse/aiql/compiler/optimizer.py +126 -0
  41. contextsynapse/aiql/compiler/planner.py +366 -0
  42. contextsynapse/aiql/compiler/statistics.py +235 -0
  43. contextsynapse/aiql/compiler/validator.py +425 -0
  44. contextsynapse/aiql/engine/__init__.py +11 -0
  45. contextsynapse/aiql/engine/chunk_storage.py +2584 -0
  46. contextsynapse/aiql/engine/executor.py +7737 -0
  47. contextsynapse/aiql/engine/extraction_integration.py +442 -0
  48. contextsynapse/aiql/engine/graph_builder.py +405 -0
  49. contextsynapse/aiql/engine/node_creation_from_normalized.py +691 -0
  50. contextsynapse/aiql/engine/performance_monitor.py +289 -0
  51. contextsynapse/aiql/engine/postprocessing.py +365 -0
  52. contextsynapse/aiql/engine/ray_stage_executors.py +918 -0
  53. contextsynapse/aiql/engine/redis_cache.py +106 -0
  54. contextsynapse/aiql/engine/streaming_json.py +366 -0
  55. contextsynapse/aiql/engine/streaming_parquet.py +568 -0
  56. contextsynapse/aiql/engine/streaming_ray_chunking.py +419 -0
  57. contextsynapse/aiql/grammar/__init__.py +14 -0
  58. contextsynapse/aiql/grammar/aiql_grammar.py +1822 -0
  59. contextsynapse/aiql/grammar/base.py +71 -0
  60. contextsynapse/aiql/parser/__init__.py +46 -0
  61. contextsynapse/aiql/parser/aiql_parser.py +11330 -0
  62. contextsynapse/aiql/parser/base_parser.py +47 -0
  63. contextsynapse/api/__init__.py +5 -0
  64. contextsynapse/api/a2a_router.py +233 -0
  65. contextsynapse/api/admin_router.py +140 -0
  66. contextsynapse/api/agent_worker_router.py +978 -0
  67. contextsynapse/api/algorithms_router.py +317 -0
  68. contextsynapse/api/api.py +4144 -0
  69. contextsynapse/api/audit.py +204 -0
  70. contextsynapse/api/auth.py +441 -0
  71. contextsynapse/api/auth_router.py +537 -0
  72. contextsynapse/api/billing.py +261 -0
  73. contextsynapse/api/billing_router.py +275 -0
  74. contextsynapse/api/boundary_router.py +452 -0
  75. contextsynapse/api/cognition_router.py +116 -0
  76. contextsynapse/api/connector_router.py +237 -0
  77. contextsynapse/api/context_router.py +1619 -0
  78. contextsynapse/api/dashboard_router.py +11367 -0
  79. contextsynapse/api/errors.py +183 -0
  80. contextsynapse/api/events.py +88 -0
  81. contextsynapse/api/experiment_bootstrap.py +321 -0
  82. contextsynapse/api/experiment_orchestrator.py +1078 -0
  83. contextsynapse/api/experiment_router.py +2089 -0
  84. contextsynapse/api/feature_gate.py +89 -0
  85. contextsynapse/api/federation_router.py +108 -0
  86. contextsynapse/api/integrations.py +567 -0
  87. contextsynapse/api/integrations_router.py +461 -0
  88. contextsynapse/api/intelligence_router.py +1028 -0
  89. contextsynapse/api/metering.py +155 -0
  90. contextsynapse/api/metrics.py +112 -0
  91. contextsynapse/api/models.py +38 -0
  92. contextsynapse/api/monitoring_router.py +174 -0
  93. contextsynapse/api/pipeline_router.py +1437 -0
  94. contextsynapse/api/playground_conn.py +116 -0
  95. contextsynapse/api/projects_router.py +131 -0
  96. contextsynapse/api/queries_router.py +282 -0
  97. contextsynapse/api/quota.py +95 -0
  98. contextsynapse/api/rate_limit.py +64 -0
  99. contextsynapse/api/search_router.py +261 -0
  100. contextsynapse/api/shield_router.py +447 -0
  101. contextsynapse/api/tenant_guard.py +103 -0
  102. contextsynapse/api/tenant_quotas.py +231 -0
  103. contextsynapse/api/tenants.py +305 -0
  104. contextsynapse/api/users.py +646 -0
  105. contextsynapse/api/v1.py +167 -0
  106. contextsynapse/api/vertical_builder_router.py +387 -0
  107. contextsynapse/benchmark/__init__.py +15 -0
  108. contextsynapse/benchmark/__main__.py +64 -0
  109. contextsynapse/benchmark/agents.py +338 -0
  110. contextsynapse/benchmark/live_ab.py +338 -0
  111. contextsynapse/benchmark/reporter.py +149 -0
  112. contextsynapse/benchmark/runner.py +264 -0
  113. contextsynapse/benchmark/savings.py +266 -0
  114. contextsynapse/benchmark/token_counter.py +212 -0
  115. contextsynapse/benchmark/workloads.py +289 -0
  116. contextsynapse/buffer/__init__.py +154 -0
  117. contextsynapse/buffer/base.py +257 -0
  118. contextsynapse/buffer/duckdb_buffer.py +246 -0
  119. contextsynapse/buffer/file_buffer.py +229 -0
  120. contextsynapse/buffer/lmdb_buffer.py +286 -0
  121. contextsynapse/buffer/local_buffer.py +154 -0
  122. contextsynapse/buffer/redis_buffer.py +211 -0
  123. contextsynapse/buffer/sqlite_buffer.py +266 -0
  124. contextsynapse/cache.py +2 -0
  125. contextsynapse/cli/__init__.py +40 -0
  126. contextsynapse/cli/cli.py +475 -0
  127. contextsynapse/cli/config_cli.py +177 -0
  128. contextsynapse/cli/scaffold.py +465 -0
  129. contextsynapse/cognition/__init__.py +31 -0
  130. contextsynapse/cognition/derivation.py +55 -0
  131. contextsynapse/cognition/events.py +135 -0
  132. contextsynapse/cognition/feedback.py +52 -0
  133. contextsynapse/cognition/hallucination.py +90 -0
  134. contextsynapse/cognition/invalidation.py +70 -0
  135. contextsynapse/cognition/read_tracker.py +50 -0
  136. contextsynapse/collaboration.py +2 -0
  137. contextsynapse/comparison.py +2 -0
  138. contextsynapse/config/__init__.py +10 -0
  139. contextsynapse/config/connectors/amfi_nav.yaml +18 -0
  140. contextsynapse/config/connectors/auto_sector.yaml +20 -0
  141. contextsynapse/config/connectors/banking_sector.yaml +20 -0
  142. contextsynapse/config/connectors/energy_sector.yaml +20 -0
  143. contextsynapse/config/connectors/fmcg_sector.yaml +20 -0
  144. contextsynapse/config/connectors/nsdl_fpi.yaml +9 -0
  145. contextsynapse/config/connectors/nse_price.yaml +61 -0
  146. contextsynapse/config/connectors/pharma_sector.yaml +20 -0
  147. contextsynapse/config/connectors/rbi_dbie.yaml +12 -0
  148. contextsynapse/config/context_presets/ai_research.json +25 -0
  149. contextsynapse/config/context_presets/chatgpt_conversations.json +19 -0
  150. contextsynapse/config/context_presets/claude_conversations.json +19 -0
  151. contextsynapse/config/context_presets/legal_compliance.json +21 -0
  152. contextsynapse/config/context_presets/meeting_notes.json +21 -0
  153. contextsynapse/config/context_presets/slack_engineering.json +21 -0
  154. contextsynapse/config/context_presets/tech_climate.json +24 -0
  155. contextsynapse/config/context_presets/toi_politics.json +25 -0
  156. contextsynapse/config/database_config.py +453 -0
  157. contextsynapse/config/deployment.py +221 -0
  158. contextsynapse/config/gpt_action_schema.json +164 -0
  159. contextsynapse/config/indicators/india_macro.yaml +213 -0
  160. contextsynapse/config/logging_config.py +88 -0
  161. contextsynapse/config/mode_config.py +223 -0
  162. contextsynapse/config/schemas/api_spec.yaml +48 -0
  163. contextsynapse/config/schemas/architecture_doc.yaml +51 -0
  164. contextsynapse/config/schemas/chat_history.yaml +90 -0
  165. contextsynapse/config/schemas/chatgpt_conversation.yaml +101 -0
  166. contextsynapse/config/schemas/claude_conversation.yaml +148 -0
  167. contextsynapse/config/schemas/contract.yaml +48 -0
  168. contextsynapse/config/schemas/conversation.yaml +167 -0
  169. contextsynapse/config/schemas/database.yaml +74 -0
  170. contextsynapse/config/schemas/decision.yaml +72 -0
  171. contextsynapse/config/schemas/ecommerce.yaml +56 -0
  172. contextsynapse/config/schemas/education.yaml +42 -0
  173. contextsynapse/config/schemas/healthcare.yaml +133 -0
  174. contextsynapse/config/schemas/hr_document.yaml +48 -0
  175. contextsynapse/config/schemas/invoice.yaml +40 -0
  176. contextsynapse/config/schemas/knowledge_base.yaml +75 -0
  177. contextsynapse/config/schemas/legal.yaml +42 -0
  178. contextsynapse/config/schemas/marketing_content.yaml +48 -0
  179. contextsynapse/config/schemas/meeting_notes.yaml +51 -0
  180. contextsynapse/config/schemas/news_article.yaml +61 -0
  181. contextsynapse/config/schemas/real_estate.yaml +49 -0
  182. contextsynapse/config/schemas/requirements_doc.yaml +48 -0
  183. contextsynapse/config/schemas/research_paper.yaml +56 -0
  184. contextsynapse/config/schemas/resume.yaml +49 -0
  185. contextsynapse/config/schemas/retail.yaml +42 -0
  186. contextsynapse/config/schemas/rule_meta.yaml +173 -0
  187. contextsynapse/config/schemas/rules.yaml +72 -0
  188. contextsynapse/config/schemas/screener_meta.yaml +236 -0
  189. contextsynapse/config/schemas/sdlc.yaml +103 -0
  190. contextsynapse/config/schemas/session_graph.yaml +172 -0
  191. contextsynapse/config/schemas/support_ticket.yaml +48 -0
  192. contextsynapse/config/schemas/web.yaml +64 -0
  193. contextsynapse/config/sensors/earnings_calendar.yaml +52 -0
  194. contextsynapse/config/sensors/global_risk.yaml +53 -0
  195. contextsynapse/config/sensors/government_policy.yaml +54 -0
  196. contextsynapse/config/sensors/supply_chain.yaml +50 -0
  197. contextsynapse/config/sensors/templates/behavioral.yaml +56 -0
  198. contextsynapse/config/sensors/templates/equity_sentiment.yaml +48 -0
  199. contextsynapse/config/sensors/templates/global_macro.yaml +47 -0
  200. contextsynapse/config/sensors/templates/market_data.yaml +118 -0
  201. contextsynapse/config/sensors/templates/sector_technical.yaml +47 -0
  202. contextsynapse/config/sensors/weather.yaml +52 -0
  203. contextsynapse/config/storage_strategy.py +202 -0
  204. contextsynapse/config/templates/competitive_intel.yaml +39 -0
  205. contextsynapse/config/templates/geopolitical_risk.yaml +46 -0
  206. contextsynapse/config/templates/market_analysis.yaml +58 -0
  207. contextsynapse/connectors/__init__.py +15 -0
  208. contextsynapse/connectors/api_router.py +121 -0
  209. contextsynapse/connectors/base.py +357 -0
  210. contextsynapse/connectors/financial/audio.py +170 -0
  211. contextsynapse/connectors/financial/youtube.py +272 -0
  212. contextsynapse/connectors/github.py +164 -0
  213. contextsynapse/connectors/jira.py +120 -0
  214. contextsynapse/connectors/kafka_connector.py +124 -0
  215. contextsynapse/connectors/pipeline_connector.py +747 -0
  216. contextsynapse/connectors/registry.py +116 -0
  217. contextsynapse/connectors/scheduler.py +87 -0
  218. contextsynapse/connectors/universal.py +360 -0
  219. contextsynapse/context/__init__.py +96 -0
  220. contextsynapse/context/__main__.py +4 -0
  221. contextsynapse/context/acl.py +125 -0
  222. contextsynapse/context/agent_card.py +201 -0
  223. contextsynapse/context/agent_memory.py +814 -0
  224. contextsynapse/context/agents.py +472 -0
  225. contextsynapse/context/agents_redis.py +391 -0
  226. contextsynapse/context/assembled.py +204 -0
  227. contextsynapse/context/attribution.py +113 -0
  228. contextsynapse/context/blob.py +184 -0
  229. contextsynapse/context/boundaries.py +187 -0
  230. contextsynapse/context/boundary.py +507 -0
  231. contextsynapse/context/bundle.py +155 -0
  232. contextsynapse/context/cli.py +519 -0
  233. contextsynapse/context/collaboration.py +165 -0
  234. contextsynapse/context/compiler.py +604 -0
  235. contextsynapse/context/composite.py +536 -0
  236. contextsynapse/context/compression.py +147 -0
  237. contextsynapse/context/context_manager.py +888 -0
  238. contextsynapse/context/context_schema.py +90 -0
  239. contextsynapse/context/context_schema.yaml +105 -0
  240. contextsynapse/context/context_units.py +891 -0
  241. contextsynapse/context/conversation.py +488 -0
  242. contextsynapse/context/dedup.py +207 -0
  243. contextsynapse/context/document_processor.py +698 -0
  244. contextsynapse/context/embedding_hooks.py +338 -0
  245. contextsynapse/context/execution_schema.py +274 -0
  246. contextsynapse/context/fan_out.py +138 -0
  247. contextsynapse/context/frozen.py +80 -0
  248. contextsynapse/context/gravity.py +227 -0
  249. contextsynapse/context/hub.py +1401 -0
  250. contextsynapse/context/ingest.py +391 -0
  251. contextsynapse/context/injection.py +226 -0
  252. contextsynapse/context/interaction_graphifier.py +562 -0
  253. contextsynapse/context/layers.py +574 -0
  254. contextsynapse/context/projection.py +1195 -0
  255. contextsynapse/context/promotion.py +634 -0
  256. contextsynapse/context/proof.py +131 -0
  257. contextsynapse/context/propagation.py +577 -0
  258. contextsynapse/context/pubsub.py +135 -0
  259. contextsynapse/context/quality.py +1054 -0
  260. contextsynapse/context/quality_tracker.py +270 -0
  261. contextsynapse/context/scoping.py +370 -0
  262. contextsynapse/context/seed.py +992 -0
  263. contextsynapse/context/session.py +1142 -0
  264. contextsynapse/context/session_graph.py +593 -0
  265. contextsynapse/context/session_memory.py +309 -0
  266. contextsynapse/context/session_resolver.py +111 -0
  267. contextsynapse/context/skill_learning.py +237 -0
  268. contextsynapse/context/smart_budget.py +129 -0
  269. contextsynapse/context/source_policy.py +242 -0
  270. contextsynapse/context/store_factory.py +53 -0
  271. contextsynapse/context/sync.py +648 -0
  272. contextsynapse/context/token.py +236 -0
  273. contextsynapse/context/vector_integration.py +297 -0
  274. contextsynapse/context/webhooks.py +194 -0
  275. contextsynapse/context/working_memory.py +224 -0
  276. contextsynapse/core/__init__.py +18 -0
  277. contextsynapse/core/archiver.py +237 -0
  278. contextsynapse/core/change_stream.py +282 -0
  279. contextsynapse/core/checkpoint.py +310 -0
  280. contextsynapse/core/cloud_storage.py +387 -0
  281. contextsynapse/core/context_state.py +651 -0
  282. contextsynapse/core/cron.py +324 -0
  283. contextsynapse/core/datasource.py +643 -0
  284. contextsynapse/core/db.py +289 -0
  285. contextsynapse/core/federation.py +283 -0
  286. contextsynapse/core/graph_coordinator.py +201 -0
  287. contextsynapse/core/graph_intelligence.py +388 -0
  288. contextsynapse/core/graph_structures.py +106 -0
  289. contextsynapse/core/graph_sync.py +157 -0
  290. contextsynapse/core/hybrid_graph_storage.py +2998 -0
  291. contextsynapse/core/lifecycle.py +691 -0
  292. contextsynapse/core/multiworker.py +378 -0
  293. contextsynapse/core/pruning.py +312 -0
  294. contextsynapse/core/redis_registry.py +524 -0
  295. contextsynapse/core/registry.py +1043 -0
  296. contextsynapse/core/registry_factory.py +51 -0
  297. contextsynapse/core/registry_metadata.py +294 -0
  298. contextsynapse/core/replay.py +354 -0
  299. contextsynapse/core/replication.py +339 -0
  300. contextsynapse/core/time_travel.py +260 -0
  301. contextsynapse/core/write_behind.py +152 -0
  302. contextsynapse/core/write_context.py +39 -0
  303. contextsynapse/db/__init__.py +1 -0
  304. contextsynapse/db/postgres.py +267 -0
  305. contextsynapse/db/profile.py +236 -0
  306. contextsynapse/db/rules.py +328 -0
  307. contextsynapse/demo/__init__.py +0 -0
  308. contextsynapse/demo/report.py +147 -0
  309. contextsynapse/demo/runner.py +520 -0
  310. contextsynapse/demo/scenario.py +165 -0
  311. contextsynapse/demo/session_demo.py +280 -0
  312. contextsynapse/demo/session_report.py +143 -0
  313. contextsynapse/demo/universal_runner.py +257 -0
  314. contextsynapse/engine/__init__.py +15 -0
  315. contextsynapse/engine/core.py +555 -0
  316. contextsynapse/extraction/__init__.py +69 -0
  317. contextsynapse/extraction/cli.py +274 -0
  318. contextsynapse/extraction/config.py +107 -0
  319. contextsynapse/extraction/examples/example_usage.py +118 -0
  320. contextsynapse/extraction/examples/sample_manifest.json +53 -0
  321. contextsynapse/extraction/examples/sample_normalized.json +185 -0
  322. contextsynapse/extraction/extract_engine.py +440 -0
  323. contextsynapse/extraction/extractors/__init__.py +37 -0
  324. contextsynapse/extraction/extractors/chat_export_extractor.py +189 -0
  325. contextsynapse/extraction/extractors/csv_extractor.py +83 -0
  326. contextsynapse/extraction/extractors/docx_extractor.py +129 -0
  327. contextsynapse/extraction/extractors/excel_extractor.py +152 -0
  328. contextsynapse/extraction/extractors/html_extractor.py +146 -0
  329. contextsynapse/extraction/extractors/pdf_extractor.py +635 -0
  330. contextsynapse/extraction/extractors/pdf_extractor_layoutparser.py +408 -0
  331. contextsynapse/extraction/extractors/register_extractors.py +63 -0
  332. contextsynapse/extraction/extractors/text_extractor.py +65 -0
  333. contextsynapse/extraction/extractors/txt_extractor.py +120 -0
  334. contextsynapse/extraction/extractors/website_extractor.py +246 -0
  335. contextsynapse/extraction/fact_extractor.py +236 -0
  336. contextsynapse/extraction/file_manager.py +353 -0
  337. contextsynapse/extraction/hierarchy.py +239 -0
  338. contextsynapse/extraction/id_generator.py +450 -0
  339. contextsynapse/extraction/layout_detector.py +409 -0
  340. contextsynapse/extraction/llm_entity_extractor.py +301 -0
  341. contextsynapse/extraction/normalized_store.py +480 -0
  342. contextsynapse/extraction/normalizer.py +594 -0
  343. contextsynapse/extraction/parquet_writer.py +598 -0
  344. contextsynapse/extraction/post_processors/__init__.py +40 -0
  345. contextsynapse/extraction/post_processors/column_reorganizer.py +507 -0
  346. contextsynapse/extraction/ray_normalization.py +233 -0
  347. contextsynapse/extraction/ray_runner.py +207 -0
  348. contextsynapse/extraction/redis_schema_registry.py +222 -0
  349. contextsynapse/extraction/registry.py +204 -0
  350. contextsynapse/extraction/schema_loader.py +663 -0
  351. contextsynapse/extraction/schema_registry.py +230 -0
  352. contextsynapse/extraction/semantic_normalizer.py +245 -0
  353. contextsynapse/extraction/version_manager.py +314 -0
  354. contextsynapse/gateway/__init__.py +24 -0
  355. contextsynapse/gateway/action_emitter.py +212 -0
  356. contextsynapse/gateway/cost_tracker.py +508 -0
  357. contextsynapse/gateway/gateway.py +377 -0
  358. contextsynapse/gateway/policy.py +303 -0
  359. contextsynapse/governance/__init__.py +13 -0
  360. contextsynapse/governance/layer.py +513 -0
  361. contextsynapse/ingestion/__init__.py +15 -0
  362. contextsynapse/ingestion/amplifier.py +288 -0
  363. contextsynapse/ingestion/async_ingest.py +463 -0
  364. contextsynapse/ingestion/chunker.py +303 -0
  365. contextsynapse/ingestion/chunking.py +58 -0
  366. contextsynapse/ingestion/cleaner.py +190 -0
  367. contextsynapse/ingestion/cleanse.py +252 -0
  368. contextsynapse/ingestion/connectors/__init__.py +38 -0
  369. contextsynapse/ingestion/connectors/base.py +300 -0
  370. contextsynapse/ingestion/connectors/chatgpt_memory.py +247 -0
  371. contextsynapse/ingestion/connectors/claude_memory.py +274 -0
  372. contextsynapse/ingestion/connectors/sap_ingestor.py +208 -0
  373. contextsynapse/ingestion/content_detector.py +80 -0
  374. contextsynapse/ingestion/content_monitor.py +502 -0
  375. contextsynapse/ingestion/dedup.py +106 -0
  376. contextsynapse/ingestion/feed.py +640 -0
  377. contextsynapse/ingestion/filters.py +461 -0
  378. contextsynapse/ingestion/graph_builder.py +705 -0
  379. contextsynapse/ingestion/input_classifier.py +307 -0
  380. contextsynapse/ingestion/job_manager.py +571 -0
  381. contextsynapse/ingestion/llm_extractor.py +610 -0
  382. contextsynapse/ingestion/orchestrator.py +116 -0
  383. contextsynapse/ingestion/parsers/__init__.py +19 -0
  384. contextsynapse/ingestion/parsers/graph_parser_registry.py +103 -0
  385. contextsynapse/ingestion/parsers/graphml_parser.py +141 -0
  386. contextsynapse/ingestion/parsers/jsonld_parser.py +171 -0
  387. contextsynapse/ingestion/parsers/rdf_parser.py +150 -0
  388. contextsynapse/ingestion/pipeline_context.py +228 -0
  389. contextsynapse/ingestion/pipeline_store.py +1195 -0
  390. contextsynapse/ingestion/queue.py +133 -0
  391. contextsynapse/ingestion/reprocess.py +179 -0
  392. contextsynapse/ingestion/scenario_router.py +224 -0
  393. contextsynapse/ingestion/schema_extractor.py +759 -0
  394. contextsynapse/ingestion/schema_validator.py +274 -0
  395. contextsynapse/ingestion/sdlc_ingest.py +87 -0
  396. contextsynapse/ingestion/smart_ingest.py +2451 -0
  397. contextsynapse/ingestion/source_connector.py +171 -0
  398. contextsynapse/ingestion/stage_executor.py +2095 -0
  399. contextsynapse/ingestion/stages/__init__.py +9 -0
  400. contextsynapse/ingestion/stages/tabular_to_graph.py +289 -0
  401. contextsynapse/ingestion/strategies.py +386 -0
  402. contextsynapse/ingestion/universal/__init__.py +4 -0
  403. contextsynapse/ingestion/universal/_operator_registry.py +59 -0
  404. contextsynapse/ingestion/universal/ingest_content.py +32 -0
  405. contextsynapse/ingestion/universal/operators/__init__.py +1 -0
  406. contextsynapse/ingestion/universal/operators/base.py +19 -0
  407. contextsynapse/ingestion/universal/operators/build_edges.py +75 -0
  408. contextsynapse/ingestion/universal/operators/cluster_topics.py +397 -0
  409. contextsynapse/ingestion/universal/operators/deduplicate.py +45 -0
  410. contextsynapse/ingestion/universal/operators/detect_signals.py +90 -0
  411. contextsynapse/ingestion/universal/operators/embed.py +80 -0
  412. contextsynapse/ingestion/universal/operators/extract_entities.py +253 -0
  413. contextsynapse/ingestion/universal/operators/extract_preferences.py +117 -0
  414. contextsynapse/ingestion/universal/operators/filter_content.py +69 -0
  415. contextsynapse/ingestion/universal/operators/index_bm25.py +52 -0
  416. contextsynapse/ingestion/universal/operators/infer_domains.py +69 -0
  417. contextsynapse/ingestion/universal/operators/link_cross_reference.py +210 -0
  418. contextsynapse/ingestion/universal/operators/parse_records.py +66 -0
  419. contextsynapse/ingestion/universal/operators/resolve_entities.py +261 -0
  420. contextsynapse/ingestion/universal/operators/scanners/__init__.py +16 -0
  421. contextsynapse/ingestion/universal/operators/scanners/edges.py +173 -0
  422. contextsynapse/ingestion/universal/operators/scanners/git.py +187 -0
  423. contextsynapse/ingestion/universal/operators/scanners/github.py +135 -0
  424. contextsynapse/ingestion/universal/operators/scanners/github_api.py +509 -0
  425. contextsynapse/ingestion/universal/operators/scanners/helpers.py +67 -0
  426. contextsynapse/ingestion/universal/operators/scanners/jira.py +65 -0
  427. contextsynapse/ingestion/universal/operators/scanners/llm_enrichment.py +82 -0
  428. contextsynapse/ingestion/universal/operators/scanners/repo.py +149 -0
  429. contextsynapse/ingestion/universal/operators/sdlc_scan.py +213 -0
  430. contextsynapse/ingestion/universal/operators/spec_scanner.py +149 -0
  431. contextsynapse/ingestion/universal/operators/store_documents.py +72 -0
  432. contextsynapse/ingestion/universal/operators/synthesize_cu.py +180 -0
  433. contextsynapse/ingestion/universal/operators/validate_gate.py +65 -0
  434. contextsynapse/ingestion/universal/parsers/__init__.py +5 -0
  435. contextsynapse/ingestion/universal/parsers/record_parser.py +203 -0
  436. contextsynapse/ingestion/universal/parsers/turn_parser.py +329 -0
  437. contextsynapse/ingestion/universal/shared_signals.py +161 -0
  438. contextsynapse/ingestion/universal/stage_executor.py +219 -0
  439. contextsynapse/ingestion/web_crawler.py +265 -0
  440. contextsynapse/intelligence/__init__.py +53 -0
  441. contextsynapse/intelligence/alerts.py +198 -0
  442. contextsynapse/intelligence/collector.py +655 -0
  443. contextsynapse/intelligence/comparison.py +198 -0
  444. contextsynapse/intelligence/config.py +56 -0
  445. contextsynapse/intelligence/conflict_detector.py +182 -0
  446. contextsynapse/intelligence/context_gaps.py +192 -0
  447. contextsynapse/intelligence/context_radar.py +135 -0
  448. contextsynapse/intelligence/correlation_engine.py +416 -0
  449. contextsynapse/intelligence/correlation_template.py +120 -0
  450. contextsynapse/intelligence/dedup.py +296 -0
  451. contextsynapse/intelligence/event_bus.py +91 -0
  452. contextsynapse/intelligence/feedback_loop.py +101 -0
  453. contextsynapse/intelligence/freshness.py +307 -0
  454. contextsynapse/intelligence/fundamental_feed.py +551 -0
  455. contextsynapse/intelligence/geo_data.py +170 -0
  456. contextsynapse/intelligence/geo_reference.py +112 -0
  457. contextsynapse/intelligence/graph_fusion.py +465 -0
  458. contextsynapse/intelligence/heuristics.py +176 -0
  459. contextsynapse/intelligence/impact_tracker.py +336 -0
  460. contextsynapse/intelligence/macro_indicators.py +319 -0
  461. contextsynapse/intelligence/ocr.py +104 -0
  462. contextsynapse/intelligence/persistence.py +267 -0
  463. contextsynapse/intelligence/pipeline_health.py +130 -0
  464. contextsynapse/intelligence/price_feed.py +221 -0
  465. contextsynapse/intelligence/rate_limiter.py +130 -0
  466. contextsynapse/intelligence/reactive.py +411 -0
  467. contextsynapse/intelligence/runtime_context.py +390 -0
  468. contextsynapse/intelligence/sentiment_decay.py +426 -0
  469. contextsynapse/intelligence/session.py +277 -0
  470. contextsynapse/intelligence/signal_hierarchy.py +438 -0
  471. contextsynapse/intelligence/signals.py +185 -0
  472. contextsynapse/intelligence/source_watcher.py +132 -0
  473. contextsynapse/intelligence/table_enricher.py +256 -0
  474. contextsynapse/intelligence/tagger.py +319 -0
  475. contextsynapse/intelligence/timeseries.py +209 -0
  476. contextsynapse/intelligence/tracker.py +318 -0
  477. contextsynapse/intelligence/watchdog.py +392 -0
  478. contextsynapse/intelligence/watchdog_manager.py +263 -0
  479. contextsynapse/intelligence/webhook_receiver.py +165 -0
  480. contextsynapse/intelligence/weight_learner.py +234 -0
  481. contextsynapse/llm/__init__.py +8 -0
  482. contextsynapse/llm/client.py +348 -0
  483. contextsynapse/llm/rate_limiter.py +166 -0
  484. contextsynapse/logging_config.py +2 -0
  485. contextsynapse/marketplace/__init__.py +7 -0
  486. contextsynapse/marketplace/registry.py +173 -0
  487. contextsynapse/mcp/__init__.py +11 -0
  488. contextsynapse/mcp/__main__.py +4 -0
  489. contextsynapse/mcp/auth_middleware.py +212 -0
  490. contextsynapse/mcp/connection_pool.py +128 -0
  491. contextsynapse/mcp/server.py +986 -0
  492. contextsynapse/mcp/session_context.py +67 -0
  493. contextsynapse/memory/__init__.py +34 -0
  494. contextsynapse/memory/engine.py +475 -0
  495. contextsynapse/memory/temporal.py +327 -0
  496. contextsynapse/metadata/__init__.py +12 -0
  497. contextsynapse/metadata/metadata_db.py +272 -0
  498. contextsynapse/metadata/metadata_query_tool.py +300 -0
  499. contextsynapse/metadata/metadata_tracker.py +425 -0
  500. contextsynapse/models/__init__.py +27 -0
  501. contextsynapse/models/embedding_service.py +360 -0
  502. contextsynapse/models/model_registry.py +228 -0
  503. contextsynapse/multiworker.py +2 -0
  504. contextsynapse/pipelines/__init__.py +1 -0
  505. contextsynapse/pipelines/executor.py +851 -0
  506. contextsynapse/pipelines/filters.py +189 -0
  507. contextsynapse/pipelines/models.py +176 -0
  508. contextsynapse/pipelines/scheduler.py +268 -0
  509. contextsynapse/playground/__init__.py +1 -0
  510. contextsynapse/playground/templates.py +85 -0
  511. contextsynapse/plugins/__init__.py +43 -0
  512. contextsynapse/plugins/api.py +66 -0
  513. contextsynapse/plugins/base.py +350 -0
  514. contextsynapse/plugins/domain_interface.py +508 -0
  515. contextsynapse/plugins/domain_loader.py +241 -0
  516. contextsynapse/plugins/loader.py +148 -0
  517. contextsynapse/plugins/registry.py +265 -0
  518. contextsynapse/project/__init__.py +11 -0
  519. contextsynapse/project/code_context.py +807 -0
  520. contextsynapse/project/connectors/__init__.py +4 -0
  521. contextsynapse/project/connectors/github_connector.py +113 -0
  522. contextsynapse/project/connectors/jira_connector.py +160 -0
  523. contextsynapse/project/graph.py +1023 -0
  524. contextsynapse/project/project_context.py +545 -0
  525. contextsynapse/project/scanner_registry.py +61 -0
  526. contextsynapse/project/schema_manager.py +322 -0
  527. contextsynapse/project/schemas/knowledge.yaml +59 -0
  528. contextsynapse/project/schemas/sdlc.yaml +369 -0
  529. contextsynapse/project/sdlc_schema.py +172 -0
  530. contextsynapse/project/spec_parser.py +85 -0
  531. contextsynapse/project/task_lock.py +181 -0
  532. contextsynapse/project/task_stream.py +203 -0
  533. contextsynapse/project/team_tools.py +537 -0
  534. contextsynapse/py.typed +0 -0
  535. contextsynapse/realtime/__init__.py +6 -0
  536. contextsynapse/realtime/collaboration.py +147 -0
  537. contextsynapse/rules/__init__.py +10 -0
  538. contextsynapse/rules/engine.py +116 -0
  539. contextsynapse/rules/evaluators/__init__.py +6 -0
  540. contextsynapse/rules/evaluators/aggregate.py +205 -0
  541. contextsynapse/rules/evaluators/custom.py +170 -0
  542. contextsynapse/rules/evaluators/pre_action.py +125 -0
  543. contextsynapse/rules/evaluators/temporal.py +129 -0
  544. contextsynapse/rules/loader.py +52 -0
  545. contextsynapse/rules/models.py +124 -0
  546. contextsynapse/rules/universal.py +393 -0
  547. contextsynapse/scheduler.py +229 -0
  548. contextsynapse/schema/__init__.py +42 -0
  549. contextsynapse/schema/compiler.py +252 -0
  550. contextsynapse/schema/composer.py +158 -0
  551. contextsynapse/schema/dedup.py +73 -0
  552. contextsynapse/schema/derivation.py +172 -0
  553. contextsynapse/schema/sdl.py +326 -0
  554. contextsynapse/schema/validation_gate.py +124 -0
  555. contextsynapse/sdk/__init__.py +63 -0
  556. contextsynapse/sdk/agent.py +214 -0
  557. contextsynapse/sdk/client.py +269 -0
  558. contextsynapse/sdk/exceptions.py +23 -0
  559. contextsynapse/sdk/models.py +78 -0
  560. contextsynapse/sdk/session.py +408 -0
  561. contextsynapse/sdk/tracked.py +218 -0
  562. contextsynapse/sdk/worker.py +266 -0
  563. contextsynapse/sdk/workspace_client.py +98 -0
  564. contextsynapse/sdk/ws.py +41 -0
  565. contextsynapse/search/__init__.py +20 -0
  566. contextsynapse/search/embedding_cache.py +140 -0
  567. contextsynapse/search/enhanced_search.py +152 -0
  568. contextsynapse/search/fulltext.py +130 -0
  569. contextsynapse/search/graph_search.py +634 -0
  570. contextsynapse/search/lmdb_index.py +1218 -0
  571. contextsynapse/search/nl_to_aiql.py +199 -0
  572. contextsynapse/search/rag.py +1346 -0
  573. contextsynapse/search/rag_cache.py +167 -0
  574. contextsynapse/search/reasoning_chain.py +231 -0
  575. contextsynapse/search/redis_search.py +207 -0
  576. contextsynapse/search/retrieval_quality.py +314 -0
  577. contextsynapse/search/semantic_query.py +455 -0
  578. contextsynapse/search/text_resolver.py +159 -0
  579. contextsynapse/search/whoosh_search.py +373 -0
  580. contextsynapse/security/__init__.py +17 -0
  581. contextsynapse/security/audit.py +297 -0
  582. contextsynapse/security/audit_logger.py +97 -0
  583. contextsynapse/security/audit_trail.py +270 -0
  584. contextsynapse/security/auth_unified.py +284 -0
  585. contextsynapse/security/auto_tagger.py +230 -0
  586. contextsynapse/security/data_security.py +218 -0
  587. contextsynapse/security/encryption.py +207 -0
  588. contextsynapse/security/identity.py +447 -0
  589. contextsynapse/security/jwt_identity.py +59 -0
  590. contextsynapse/security/middleware.py +336 -0
  591. contextsynapse/security/pii.py +233 -0
  592. contextsynapse/security/rbac.py +96 -0
  593. contextsynapse/security/rls.py +205 -0
  594. contextsynapse/security/sanitize.py +233 -0
  595. contextsynapse/security/scoped_encryption.py +131 -0
  596. contextsynapse/security/tenant.py +401 -0
  597. contextsynapse/shield/__init__.py +21 -0
  598. contextsynapse/shield/anomaly.py +56 -0
  599. contextsynapse/shield/permissions.py +99 -0
  600. contextsynapse/shield/profile.py +103 -0
  601. contextsynapse/shield/shield.py +108 -0
  602. contextsynapse/shield/trust_engine.py +69 -0
  603. contextsynapse/skills/__init__.py +14 -0
  604. contextsynapse/skills/engine.py +233 -0
  605. contextsynapse/skills/loader.py +59 -0
  606. contextsynapse/skills/models.py +139 -0
  607. contextsynapse/storage/__init__.py +7 -0
  608. contextsynapse/storage/cache.py +208 -0
  609. contextsynapse/storage/columnar_store_v2.py +178 -0
  610. contextsynapse/storage/csr_graph_storage.py +587 -0
  611. contextsynapse/storage/csr_store.py +388 -0
  612. contextsynapse/storage/document_store.py +491 -0
  613. contextsynapse/storage/hnsw_index.py +294 -0
  614. contextsynapse/storage/hybrid_store_v2.py +278 -0
  615. contextsynapse/storage/lmdb_graph_storage.py +366 -0
  616. contextsynapse/storage/migration.py +279 -0
  617. contextsynapse/storage/namespace_store.py +346 -0
  618. contextsynapse/storage/pure_graph_storage.py +185 -0
  619. contextsynapse/storage/redis_graph_adapter.py +186 -0
  620. contextsynapse/storage/redis_graph_storage.py +375 -0
  621. contextsynapse/storage/router/__init__.py +29 -0
  622. contextsynapse/storage/router/duckdb_store.py +398 -0
  623. contextsynapse/storage/router/factory.py +83 -0
  624. contextsynapse/storage/router/interface.py +125 -0
  625. contextsynapse/storage/router/postgres_store.py +339 -0
  626. contextsynapse/storage/router/resolver.py +192 -0
  627. contextsynapse/storage/router/router.py +300 -0
  628. contextsynapse/storage/single_file_storage.py +391 -0
  629. contextsynapse/storage/storage_manager.py +214 -0
  630. contextsynapse/storage/storage_query_optimizer.py +314 -0
  631. contextsynapse/storage/wal.py +359 -0
  632. contextsynapse/temporal/__init__.py +0 -0
  633. contextsynapse/temporal/storage.py +106 -0
  634. contextsynapse/tests/__init__.py +11 -0
  635. contextsynapse/tests/regression/__init__.py +1 -0
  636. contextsynapse/tests/regression/add_metadata.py +395 -0
  637. contextsynapse/tests/regression/add_skip_flags.py +85 -0
  638. contextsynapse/tests/regression/cases/test_basic_create_node.yaml +20 -0
  639. contextsynapse/tests/regression/cases/test_basic_select.yaml +21 -0
  640. contextsynapse/tests/regression/cases/test_blockchain_audit_trail.yaml +37 -0
  641. contextsynapse/tests/regression/cases/test_blockchain_audit_trail_filtered.yaml +39 -0
  642. contextsynapse/tests/regression/cases/test_blockchain_blocks_range.yaml +39 -0
  643. contextsynapse/tests/regression/cases/test_blockchain_get_block.yaml +35 -0
  644. contextsynapse/tests/regression/cases/test_blockchain_latest_block.yaml +35 -0
  645. contextsynapse/tests/regression/cases/test_blockchain_length.yaml +37 -0
  646. contextsynapse/tests/regression/cases/test_blockchain_merkle_root.yaml +37 -0
  647. contextsynapse/tests/regression/cases/test_blockchain_verify.yaml +35 -0
  648. contextsynapse/tests/regression/cases/test_blockchain_verify_block.yaml +35 -0
  649. contextsynapse/tests/regression/cases/test_create_edge.yaml +28 -0
  650. contextsynapse/tests/regression/cases/test_delete_edge_basic.yaml +29 -0
  651. contextsynapse/tests/regression/cases/test_delete_node_basic.yaml +29 -0
  652. contextsynapse/tests/regression/cases/test_evaluation_mrr.yaml +40 -0
  653. contextsynapse/tests/regression/cases/test_evaluation_ndcg.yaml +40 -0
  654. contextsynapse/tests/regression/cases/test_evaluation_precision.yaml +40 -0
  655. contextsynapse/tests/regression/cases/test_evaluation_recall.yaml +40 -0
  656. contextsynapse/tests/regression/cases/test_group_by_basic.yaml +56 -0
  657. contextsynapse/tests/regression/cases/test_match_node_basic.yaml +29 -0
  658. contextsynapse/tests/regression/cases/test_match_node_with_order_limit.yaml +31 -0
  659. contextsynapse/tests/regression/cases/test_namespace_switch.yaml +18 -0
  660. contextsynapse/tests/regression/cases/test_pipeline_cascaded.yaml +61 -0
  661. contextsynapse/tests/regression/cases/test_pipeline_fixed_size_chunking.yaml +48 -0
  662. contextsynapse/tests/regression/cases/test_pipeline_gpt4_chunking.yaml +54 -0
  663. contextsynapse/tests/regression/cases/test_pipeline_hybrid_indexing.yaml +57 -0
  664. contextsynapse/tests/regression/cases/test_pipeline_large_embedding.yaml +52 -0
  665. contextsynapse/tests/regression/cases/test_pipeline_paragraph_chunking.yaml +49 -0
  666. contextsynapse/tests/regression/cases/test_pipeline_recursive_chunking.yaml +47 -0
  667. contextsynapse/tests/regression/cases/test_pipeline_run_pipeline.yaml +56 -0
  668. contextsynapse/tests/regression/cases/test_pipeline_section_based_chunking.yaml +53 -0
  669. contextsynapse/tests/regression/cases/test_pipeline_semantic_chunking.yaml +51 -0
  670. contextsynapse/tests/regression/cases/test_pipeline_with_entity_extraction.yaml +57 -0
  671. contextsynapse/tests/regression/cases/test_pipeline_with_relationships.yaml +62 -0
  672. contextsynapse/tests/regression/cases/test_rag_evaluation.yaml +38 -0
  673. contextsynapse/tests/regression/cases/test_rag_graph_bfs_with_eval.yaml +48 -0
  674. contextsynapse/tests/regression/cases/test_rag_graph_centrality.yaml +40 -0
  675. contextsynapse/tests/regression/cases/test_rag_graph_centrality_eval.yaml +35 -0
  676. contextsynapse/tests/regression/cases/test_rag_graph_community.yaml +40 -0
  677. contextsynapse/tests/regression/cases/test_rag_graph_community_eval.yaml +35 -0
  678. contextsynapse/tests/regression/cases/test_rag_graph_dfs_with_eval.yaml +35 -0
  679. contextsynapse/tests/regression/cases/test_rag_graph_multi_hop_eval.yaml +35 -0
  680. contextsynapse/tests/regression/cases/test_rag_graph_path.yaml +40 -0
  681. contextsynapse/tests/regression/cases/test_rag_graph_search_basic.yaml +38 -0
  682. contextsynapse/tests/regression/cases/test_rag_graph_search_bfs.yaml +52 -0
  683. contextsynapse/tests/regression/cases/test_rag_graph_search_dfs.yaml +41 -0
  684. contextsynapse/tests/regression/cases/test_rag_graph_search_multi_hop.yaml +43 -0
  685. contextsynapse/tests/regression/cases/test_rag_graph_search_shortest_path.yaml +41 -0
  686. contextsynapse/tests/regression/cases/test_rag_graph_search_weighted.yaml +43 -0
  687. contextsynapse/tests/regression/cases/test_rag_graph_shortest_path_eval.yaml +35 -0
  688. contextsynapse/tests/regression/cases/test_rag_graph_traversal.yaml +30 -0
  689. contextsynapse/tests/regression/cases/test_rag_graph_weighted_eval.yaml +35 -0
  690. contextsynapse/tests/regression/cases/test_rag_hybrid_search.yaml +33 -0
  691. contextsynapse/tests/regression/cases/test_rag_hybrid_with_prompt_embedding.yaml +44 -0
  692. contextsynapse/tests/regression/cases/test_rag_keyword_search.yaml +32 -0
  693. contextsynapse/tests/regression/cases/test_rag_multi_hop_graph.yaml +32 -0
  694. contextsynapse/tests/regression/cases/test_rag_path_based.yaml +34 -0
  695. contextsynapse/tests/regression/cases/test_rag_profile_based.yaml +32 -0
  696. contextsynapse/tests/regression/cases/test_rag_vector_search.yaml +32 -0
  697. contextsynapse/tests/regression/cases/test_rag_weighted_graph.yaml +34 -0
  698. contextsynapse/tests/regression/cases/test_rag_weighted_hybrid.yaml +31 -0
  699. contextsynapse/tests/regression/cases/test_semantic_boundary_chunking.yaml +57 -0
  700. contextsynapse/tests/regression/cases/test_semantic_boundary_detection.yaml +33 -0
  701. contextsynapse/tests/regression/cases/test_semantic_hash_function.yaml +30 -0
  702. contextsynapse/tests/regression/cases/test_semantic_hash_with_model.yaml +31 -0
  703. contextsynapse/tests/regression/cases/test_tcs_ingestion_fixed_size.yaml +44 -0
  704. contextsynapse/tests/regression/cases/test_tcs_ingestion_recursive.yaml +46 -0
  705. contextsynapse/tests/regression/cases/test_tcs_ingestion_section.yaml +46 -0
  706. contextsynapse/tests/regression/cases/test_tcs_ingestion_semantic.yaml +44 -0
  707. contextsynapse/tests/regression/cases/test_time_travel_as_of.yaml +35 -0
  708. contextsynapse/tests/regression/cases/test_time_travel_at_commit.yaml +33 -0
  709. contextsynapse/tests/regression/cases/test_time_travel_at_timestamp.yaml +33 -0
  710. contextsynapse/tests/regression/cases/test_time_travel_for_system_time_all.yaml +37 -0
  711. contextsynapse/tests/regression/cases/test_time_travel_versions_between.yaml +39 -0
  712. contextsynapse/tests/regression/cases/test_traverse_basic.yaml +31 -0
  713. contextsynapse/tests/regression/cases/test_traverse_max_depth.yaml +34 -0
  714. contextsynapse/tests/regression/cases/test_update_edge_basic.yaml +29 -0
  715. contextsynapse/tests/regression/evaluation_metrics.py +227 -0
  716. contextsynapse/tests/regression/regression_runner.py +1081 -0
  717. contextsynapse/tests/regression/setup_regression_data.py +212 -0
  718. contextsynapse/tests/regression/test_basic_only.py +84 -0
  719. contextsynapse/tests/regression/test_namespace_creation.py +29 -0
  720. contextsynapse/tests/regression/test_single_fix.py +61 -0
  721. contextsynapse/tests/regression/test_single_query.py +20 -0
  722. contextsynapse/tests/regression/validate_test_syntax.py +179 -0
  723. contextsynapse/tests/test_advanced_features.py +347 -0
  724. contextsynapse/tests/test_aiql_summary.py +283 -0
  725. contextsynapse/tests/test_all_aiql_queries.py +948 -0
  726. contextsynapse/tests/test_all_create_queries.py +213 -0
  727. contextsynapse/tests/test_api_vs_native.py +280 -0
  728. contextsynapse/tests/test_chunking_dedup.py +199 -0
  729. contextsynapse/tests/test_connectors.py +171 -0
  730. contextsynapse/tests/test_edges_and_match.py +202 -0
  731. contextsynapse/tests/test_extraction_pipeline_integration.py +581 -0
  732. contextsynapse/tests/test_name_property.py +224 -0
  733. contextsynapse/tests/test_node_edge_metadata.py +250 -0
  734. contextsynapse/tests/test_playground_conn.py +114 -0
  735. contextsynapse/tests/test_query_cache.py +213 -0
  736. contextsynapse/tests/test_source_policy_auth.py +348 -0
  737. contextsynapse/tests/test_temporal_and_domain.py +224 -0
  738. contextsynapse/tests/test_time_travel_e2e.py +571 -0
  739. contextsynapse/tests/test_traversal_and_aggregation.py +275 -0
  740. contextsynapse/tools/__init__.py +36 -0
  741. contextsynapse/tools/a2a_tools.py +106 -0
  742. contextsynapse/tools/cognition_tools.py +118 -0
  743. contextsynapse/tools/context.py +905 -0
  744. contextsynapse/tools/formatting.py +92 -0
  745. contextsynapse/tools/gateway_tools.py +186 -0
  746. contextsynapse/tools/graph.py +1700 -0
  747. contextsynapse/tools/intelligence.py +235 -0
  748. contextsynapse/tools/memory.py +118 -0
  749. contextsynapse/tools/registry.py +373 -0
  750. contextsynapse/tools/shield_tools.py +159 -0
  751. contextsynapse/tools/tasks.py +341 -0
  752. contextsynapse/tools/workspace_tools.py +124 -0
  753. contextsynapse/utils/__init__.py +15 -0
  754. contextsynapse/utils/config_loader.py +198 -0
  755. contextsynapse/utils/env_loader.py +156 -0
  756. contextsynapse/utils/file_utils.py +288 -0
  757. contextsynapse/utils/logging_optimizer.py +119 -0
  758. contextsynapse/vector/__init__.py +30 -0
  759. contextsynapse/vector/chroma_vector_store.py +152 -0
  760. contextsynapse/vector/custom_vector_store.py +537 -0
  761. contextsynapse/vector/faiss_vector_store.py +296 -0
  762. contextsynapse/vector/qdrant_vector_store.py +163 -0
  763. contextsynapse/vector/vector_db.py +953 -0
  764. contextsynapse/vector/vector_db_manager.py +197 -0
  765. contextsynapse/workspace/__init__.py +27 -0
  766. contextsynapse/workspace/base.py +94 -0
  767. contextsynapse/workspace/git.py +228 -0
  768. contextsynapse/workspace/github.py +78 -0
  769. contextsynapse/workspace/local.py +73 -0
  770. contextsynapse/workspace/tools.py +222 -0
  771. contextsynapse-1.0.0.dist-info/METADATA +847 -0
  772. contextsynapse-1.0.0.dist-info/RECORD +776 -0
  773. contextsynapse-1.0.0.dist-info/WHEEL +5 -0
  774. contextsynapse-1.0.0.dist-info/entry_points.txt +4 -0
  775. contextsynapse-1.0.0.dist-info/licenses/LICENSE +200 -0
  776. contextsynapse-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,338 @@
1
+ """
2
+ Benchmark Agents
3
+ =================
4
+ Simulated agent behavior for the benchmark.
5
+ Each agent does a specific job (extract, analyze, summarize).
6
+
7
+ Two modes:
8
+ - Baseline: Each agent works independently (no shared context)
9
+ - Shared: Agents share a graph via AIContextDB
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import logging
16
+ from typing import Any, Dict, List, Optional
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+ EXTRACT_SYSTEM = """You are an entity extraction agent. Extract all entities,
21
+ relationships, and key facts from the given document.
22
+
23
+ Return JSON with this structure:
24
+ {
25
+ "entities": [
26
+ {"name": "...", "type": "...", "description": "..."}
27
+ ],
28
+ "relationships": [
29
+ {"source": "...", "target": "...", "type": "...", "description": "..."}
30
+ ],
31
+ "facts": [
32
+ {"statement": "...", "confidence": 0.9}
33
+ ]
34
+ }"""
35
+
36
+ ANALYZE_SYSTEM = """You are an analysis agent. Given a set of entities and
37
+ relationships, identify:
38
+ 1. Key decisions and their rationale
39
+ 2. Risks and mitigation strategies
40
+ 3. Dependencies between components
41
+ 4. Priority recommendations
42
+
43
+ Return JSON:
44
+ {
45
+ "decisions": [{"title": "...", "rationale": "...", "impact": "high/medium/low"}],
46
+ "risks": [{"description": "...", "severity": "high/medium/low", "mitigation": "..."}],
47
+ "dependencies": [{"from": "...", "to": "...", "type": "..."}],
48
+ "recommendations": ["..."]
49
+ }"""
50
+
51
+ SUMMARIZE_SYSTEM = """You are a summarization agent. Given context about a
52
+ document's entities, decisions, and risks, produce a concise executive summary.
53
+
54
+ Return JSON:
55
+ {
56
+ "summary": "2-3 paragraph executive summary",
57
+ "key_points": ["point 1", "point 2", ...],
58
+ "action_items": ["item 1", "item 2", ...]
59
+ }"""
60
+
61
+
62
+ class BaselineAgents:
63
+ """Agents that work independently — NO shared context.
64
+
65
+ Each agent receives the raw document and does all work from scratch.
66
+ This is the "expensive" baseline that we measure against.
67
+ """
68
+
69
+ def __init__(self, llm_client):
70
+ """
71
+ Args:
72
+ llm_client: TokenCountingClient instance
73
+ """
74
+ self.llm = llm_client
75
+
76
+ def run_extractor(self, document: str) -> Dict[str, Any]:
77
+ """Agent 1: Extract entities from raw document."""
78
+ result = self.llm.generate_json(
79
+ prompt=f"Extract all entities, relationships, and facts from this document:\n\n{document}",
80
+ system=EXTRACT_SYSTEM,
81
+ operation="extract",
82
+ agent_id="baseline_extractor",
83
+ )
84
+ return result
85
+
86
+ def run_analyst(self, document: str) -> Dict[str, Any]:
87
+ """Agent 2: Analyze the document — independently re-reads everything."""
88
+ # In baseline mode, the analyst ALSO calls the LLM to extract entities
89
+ # because it has no access to what the extractor already found.
90
+ entities = self.llm.generate_json(
91
+ prompt=f"Extract all entities and relationships from this document:\n\n{document}",
92
+ system=EXTRACT_SYSTEM,
93
+ operation="extract_duplicate",
94
+ agent_id="baseline_analyst",
95
+ )
96
+
97
+ # Then analyze
98
+ result = self.llm.generate_json(
99
+ prompt=f"Analyze these entities and relationships:\n\n{json.dumps(entities, indent=2)}",
100
+ system=ANALYZE_SYSTEM,
101
+ operation="analyze",
102
+ agent_id="baseline_analyst",
103
+ )
104
+ return result
105
+
106
+ def run_summarizer(self, document: str) -> Dict[str, Any]:
107
+ """Agent 3: Summarize — independently re-reads everything."""
108
+ # In baseline mode, the summarizer ALSO re-extracts and re-analyzes
109
+ entities = self.llm.generate_json(
110
+ prompt=f"Extract key entities and facts from this document:\n\n{document}",
111
+ system=EXTRACT_SYSTEM,
112
+ operation="extract_duplicate",
113
+ agent_id="baseline_summarizer",
114
+ )
115
+
116
+ result = self.llm.generate_json(
117
+ prompt=(
118
+ f"Summarize this document based on these entities:\n\n"
119
+ f"Entities: {json.dumps(entities, indent=2)}\n\n"
120
+ f"Original document:\n{document[:2000]}" # truncated
121
+ ),
122
+ system=SUMMARIZE_SYSTEM,
123
+ operation="summarize",
124
+ agent_id="baseline_summarizer",
125
+ )
126
+ return result
127
+
128
+ def run_all(self, document: str) -> Dict[str, Any]:
129
+ """Run all 3 agents on a document (baseline mode)."""
130
+ extraction = self.run_extractor(document)
131
+ analysis = self.run_analyst(document)
132
+ summary = self.run_summarizer(document)
133
+ return {
134
+ "extraction": extraction,
135
+ "analysis": analysis,
136
+ "summary": summary,
137
+ }
138
+
139
+
140
+ class SharedAgents:
141
+ """Agents that share a graph via AIContextDB.
142
+
143
+ Agent 1 extracts and stores in graph.
144
+ Agents 2 and 3 query the graph instead of re-extracting.
145
+ This is the "efficient" mode.
146
+ """
147
+
148
+ def __init__(self, llm_client, conn=None):
149
+ """
150
+ Args:
151
+ llm_client: TokenCountingClient instance
152
+ conn: AIContextDBConnection for shared graph
153
+ """
154
+ self.llm = llm_client
155
+ self.conn = conn
156
+
157
+ def run_extractor(self, document: str) -> Dict[str, Any]:
158
+ """Agent 1: Extract entities and store in shared graph."""
159
+ result = self.llm.generate_json(
160
+ prompt=f"Extract all entities, relationships, and facts from this document:\n\n{document}",
161
+ system=EXTRACT_SYSTEM,
162
+ operation="extract",
163
+ agent_id="shared_extractor",
164
+ )
165
+
166
+ # Store in graph (free — no LLM cost)
167
+ if self.conn:
168
+ self._store_in_graph(result)
169
+
170
+ return result
171
+
172
+ def run_analyst(self, document: str) -> Dict[str, Any]:
173
+ """Agent 2: Query graph for entities, then analyze.
174
+
175
+ KEY DIFFERENCE: No LLM call for extraction — queries the graph instead.
176
+ """
177
+ # Query graph for entities (FREE — local graph query, no LLM)
178
+ entities = self._query_graph_entities()
179
+
180
+ if not entities:
181
+ # Fallback: if graph is empty, do minimal extraction
182
+ entities = {"entities": [], "relationships": [], "facts": []}
183
+
184
+ # Analyze (still needs LLM for reasoning)
185
+ result = self.llm.generate_json(
186
+ prompt=f"Analyze these entities and relationships:\n\n{json.dumps(entities, indent=2)}",
187
+ system=ANALYZE_SYSTEM,
188
+ operation="analyze",
189
+ agent_id="shared_analyst",
190
+ )
191
+
192
+ # Store analysis results in graph too
193
+ if self.conn:
194
+ self._store_analysis(result)
195
+
196
+ return result
197
+
198
+ def run_summarizer(self, document: str) -> Dict[str, Any]:
199
+ """Agent 3: Get scoped context from graph, then summarize.
200
+
201
+ KEY DIFFERENCE: Gets pre-built context from ContextHub instead of
202
+ re-reading the entire document + re-extracting entities.
203
+ """
204
+ # Build scoped context from graph (FREE — local, no LLM)
205
+ context = self._build_context()
206
+
207
+ # Summarize using scoped context (smaller input = fewer tokens)
208
+ result = self.llm.generate_json(
209
+ prompt=f"Summarize based on this context:\n\n{context}",
210
+ system=SUMMARIZE_SYSTEM,
211
+ operation="summarize",
212
+ agent_id="shared_summarizer",
213
+ )
214
+ return result
215
+
216
+ def run_all(self, document: str) -> Dict[str, Any]:
217
+ """Run all 3 agents on a document (shared mode)."""
218
+ extraction = self.run_extractor(document)
219
+ analysis = self.run_analyst(document)
220
+ summary = self.run_summarizer(document)
221
+ return {
222
+ "extraction": extraction,
223
+ "analysis": analysis,
224
+ "summary": summary,
225
+ }
226
+
227
+ def _store_in_graph(self, extraction: Dict[str, Any]):
228
+ """Store extracted entities in the shared graph."""
229
+ try:
230
+ for entity in extraction.get("entities", []):
231
+ self.conn.add_node(
232
+ label=entity.get("type", "Entity"),
233
+ properties={
234
+ "name": entity.get("name", ""),
235
+ "description": entity.get("description", ""),
236
+ "_source": "benchmark_extractor",
237
+ },
238
+ )
239
+ for rel in extraction.get("relationships", []):
240
+ # Find source and target nodes
241
+ nodes = self.conn.get_nodes()
242
+ source_id = target_id = None
243
+ for n in nodes:
244
+ props = n.properties or {}
245
+ if props.get("name") == rel.get("source"):
246
+ source_id = n.id
247
+ if props.get("name") == rel.get("target"):
248
+ target_id = n.id
249
+ if source_id and target_id:
250
+ self.conn.add_edge(
251
+ source=source_id,
252
+ target=target_id,
253
+ label=rel.get("type", "RELATED_TO"),
254
+ properties={"description": rel.get("description", "")},
255
+ )
256
+ for fact in extraction.get("facts", []):
257
+ self.conn.add_node(
258
+ label="Fact",
259
+ properties={
260
+ "statement": fact.get("statement", ""),
261
+ "confidence": fact.get("confidence", 0.5),
262
+ },
263
+ )
264
+ except Exception as e:
265
+ logger.debug("Failed to store in graph: %s", e)
266
+
267
+ def _query_graph_entities(self) -> Dict[str, Any]:
268
+ """Query the shared graph for entities (no LLM cost)."""
269
+ entities = []
270
+ relationships = []
271
+ facts = []
272
+ try:
273
+ for node in self.conn.get_nodes():
274
+ props = node.properties or {}
275
+ if node.label == "Fact":
276
+ facts.append({
277
+ "statement": props.get("statement", ""),
278
+ "confidence": props.get("confidence", 0.5),
279
+ })
280
+ else:
281
+ entities.append({
282
+ "name": props.get("name", ""),
283
+ "type": node.label,
284
+ "description": props.get("description", ""),
285
+ })
286
+
287
+ for edge in self.conn.get_edges():
288
+ relationships.append({
289
+ "source": edge.source,
290
+ "target": edge.target,
291
+ "type": edge.label,
292
+ })
293
+ except Exception as e:
294
+ logger.debug("Failed to query graph: %s", e)
295
+
296
+ return {"entities": entities, "relationships": relationships, "facts": facts}
297
+
298
+ def _store_analysis(self, analysis: Dict[str, Any]):
299
+ """Store analysis results in graph."""
300
+ try:
301
+ for decision in analysis.get("decisions", []):
302
+ self.conn.add_node(
303
+ label="Decision",
304
+ properties={
305
+ "title": decision.get("title", ""),
306
+ "rationale": decision.get("rationale", ""),
307
+ "impact": decision.get("impact", "medium"),
308
+ },
309
+ )
310
+ for risk in analysis.get("risks", []):
311
+ self.conn.add_node(
312
+ label="Risk",
313
+ properties={
314
+ "description": risk.get("description", ""),
315
+ "severity": risk.get("severity", "medium"),
316
+ "mitigation": risk.get("mitigation", ""),
317
+ },
318
+ )
319
+ except Exception as e:
320
+ logger.debug("Failed to store analysis: %s", e)
321
+
322
+ def _build_context(self) -> str:
323
+ """Build scoped context from graph (no LLM cost)."""
324
+ try:
325
+ hub = self.conn.build_context(
326
+ system_prompt="You are analyzing a document.",
327
+ max_tokens=4000,
328
+ )
329
+ return hub.to_prompt(budget=4000)
330
+ except Exception:
331
+ # Fallback: manually build context from graph
332
+ lines = []
333
+ for node in self.conn.get_nodes():
334
+ props = node.properties or {}
335
+ name = props.get("name") or props.get("title") or props.get("statement", "")
336
+ if name:
337
+ lines.append(f"[{node.label}] {name}: {props.get('description', props.get('rationale', ''))}")
338
+ return "\n".join(lines[:50]) # Cap at 50 items
@@ -0,0 +1,338 @@
1
+ """
2
+ Live A/B Benchmark — Run same questions with and without shared context.
3
+
4
+ Uses the user's actual graph data. Measures real token usage, latency,
5
+ and answer quality for both paths.
6
+
7
+ Usage:
8
+ from contextsynapse.benchmark.live_ab import run_live_ab
9
+ result = run_live_ab(graph_registry, "my_graph", questions=["What bugs exist?"])
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ import time
16
+ from typing import Any, Dict, List, Optional
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ def run_live_ab(
22
+ graph_registry,
23
+ graph_name: str,
24
+ questions: Optional[List[str]] = None,
25
+ model: Optional[str] = None,
26
+ score_quality: bool = True,
27
+ ) -> Dict[str, Any]:
28
+ """Run A/B benchmark on a real graph.
29
+
30
+ Path A (WITH AIContextDB): Uses ask/rag_query tools — gets targeted context
31
+ Path B (WITHOUT — baseline): Dumps entire graph as text, sends to LLM
32
+
33
+ Returns:
34
+ {
35
+ questions: [...],
36
+ path_a: {total_tokens, total_cost, avg_latency_ms, answers: [...]},
37
+ path_b: {total_tokens, total_cost, avg_latency_ms, answers: [...]},
38
+ savings: {tokens_saved, savings_pct, cost_saved, speedup},
39
+ }
40
+ """
41
+ db = graph_registry.get_graph(graph_name) if graph_registry else None
42
+ if not db:
43
+ return {"error": f"Graph '{graph_name}' not found"}
44
+
45
+ # Get all nodes for baseline dump
46
+ all_nodes = db.get_all_nodes()
47
+ if not all_nodes:
48
+ return {"error": "Graph is empty — ingest data first"}
49
+
50
+ # Build full graph dump text (what you'd need WITHOUT AIContextDB)
51
+ full_dump = _build_full_dump(all_nodes)
52
+ full_dump_tokens = len(full_dump) // 4
53
+
54
+ # Default questions if none provided
55
+ if not questions:
56
+ questions = _generate_questions(all_nodes)
57
+
58
+ # Get LLM
59
+ try:
60
+ from contextsynapse.llm.client import LLMClient
61
+ llm = LLMClient()
62
+ except Exception as e:
63
+ return {"error": f"LLM not available: {e}"}
64
+
65
+ # --- Path A: WITH AIContextDB (targeted retrieval) ---
66
+ path_a_results = []
67
+ for q in questions:
68
+ result = _run_path_a(db, graph_name, q, llm)
69
+ path_a_results.append(result)
70
+
71
+ # --- Path B: WITHOUT AIContextDB (full dump baseline) ---
72
+ path_b_results = []
73
+ for q in questions:
74
+ result = _run_path_b(full_dump, q, llm)
75
+ path_b_results.append(result)
76
+
77
+ # --- Aggregate ---
78
+ a_tokens = sum(r["tokens"] for r in path_a_results)
79
+ b_tokens = sum(r["tokens"] for r in path_b_results)
80
+ a_cost = sum(r["cost"] for r in path_a_results)
81
+ b_cost = sum(r["cost"] for r in path_b_results)
82
+ a_latency = sum(r["latency_ms"] for r in path_a_results) / len(path_a_results) if path_a_results else 0
83
+ b_latency = sum(r["latency_ms"] for r in path_b_results) / len(path_b_results) if path_b_results else 0
84
+
85
+ tokens_saved = max(0, b_tokens - a_tokens)
86
+ savings_pct = round(tokens_saved / b_tokens * 100, 1) if b_tokens > 0 else 0
87
+ cost_saved = max(0, b_cost - a_cost)
88
+ speedup = round(b_latency / a_latency, 1) if a_latency > 0 else 0
89
+
90
+ # --- Precision & Quality scoring (optional — uses extra LLM calls) ---
91
+ precision_results = _score_precision(questions, path_a_results, path_b_results, llm) if score_quality else []
92
+
93
+ avg_precision = 0.0
94
+ avg_quality_a = 0.0
95
+ avg_quality_b = 0.0
96
+ if precision_results:
97
+ avg_precision = round(sum(p["precision"] for p in precision_results) / len(precision_results), 2)
98
+ avg_quality_a = round(sum(p["quality_a"] for p in precision_results) / len(precision_results), 2)
99
+ avg_quality_b = round(sum(p["quality_b"] for p in precision_results) / len(precision_results), 2)
100
+
101
+ return {
102
+ "graph": graph_name,
103
+ "graph_nodes": len(all_nodes),
104
+ "graph_dump_tokens": full_dump_tokens,
105
+ "questions": questions,
106
+ "question_count": len(questions),
107
+
108
+ "with_contextcore": {
109
+ "total_tokens": a_tokens,
110
+ "total_cost_usd": round(a_cost, 6),
111
+ "avg_latency_ms": round(a_latency),
112
+ "avg_tokens_per_query": round(a_tokens / len(questions)) if questions else 0,
113
+ "avg_quality_score": avg_quality_a,
114
+ "answers": [{"question": q, **r} for q, r in zip(questions, path_a_results)],
115
+ },
116
+ "without_contextcore": {
117
+ "total_tokens": b_tokens,
118
+ "total_cost_usd": round(b_cost, 6),
119
+ "avg_latency_ms": round(b_latency),
120
+ "avg_tokens_per_query": round(b_tokens / len(questions)) if questions else 0,
121
+ "avg_quality_score": avg_quality_b,
122
+ "answers": [{"question": q, **r} for q, r in zip(questions, path_b_results)],
123
+ },
124
+ "savings": {
125
+ "tokens_saved": tokens_saved,
126
+ "savings_pct": savings_pct,
127
+ "cost_saved_usd": round(cost_saved, 6),
128
+ "speedup": f"{speedup}x",
129
+ },
130
+ "quality": {
131
+ "context_precision": avg_precision,
132
+ "quality_with_contextcore": avg_quality_a,
133
+ "quality_without_contextcore": avg_quality_b,
134
+ "quality_delta": round(avg_quality_a - avg_quality_b, 2),
135
+ "verdict": (
136
+ "AIContextDB answers are equivalent or better"
137
+ if avg_quality_a >= avg_quality_b - 0.5
138
+ else "Full context produces slightly better answers (consider tuning retrieval k)"
139
+ ),
140
+ "per_question": precision_results,
141
+ },
142
+ }
143
+
144
+
145
+ def _score_precision(
146
+ questions: List[str],
147
+ path_a_results: List[Dict],
148
+ path_b_results: List[Dict],
149
+ llm,
150
+ ) -> List[Dict[str, Any]]:
151
+ """Use LLM as judge to score answer quality and context precision.
152
+
153
+ For each question, compares Path A (targeted) vs Path B (full dump) answers.
154
+ Returns per-question scores:
155
+ - precision: 0-10 (did retrieval find the right context?)
156
+ - quality_a: 0-10 (how good is the AIContextDB answer?)
157
+ - quality_b: 0-10 (how good is the full-dump answer?)
158
+ - missing: what Path A missed that Path B caught
159
+ """
160
+ results = []
161
+
162
+ for i, question in enumerate(questions):
163
+ answer_a = path_a_results[i].get("answer", "") if i < len(path_a_results) else ""
164
+ answer_b = path_b_results[i].get("answer", "") if i < len(path_b_results) else ""
165
+
166
+ if not answer_a and not answer_b:
167
+ results.append({"precision": 5, "quality_a": 0, "quality_b": 0, "missing": "", "judge_reasoning": "Both empty"})
168
+ continue
169
+
170
+ try:
171
+ import re
172
+ prompt = (
173
+ f"You are an impartial answer quality judge.\n\n"
174
+ f"Question: {question}\n\n"
175
+ f"Answer A (from targeted retrieval — 5 relevant nodes):\n{answer_a[:500]}\n\n"
176
+ f"Answer B (from full context dump — all nodes):\n{answer_b[:500]}\n\n"
177
+ f"Score each answer 0-10 on completeness, accuracy, and relevance.\n"
178
+ f"Also rate retrieval precision 0-10: did Answer A cover the same key points as Answer B?\n"
179
+ f"Note what (if anything) Answer A missed that Answer B caught.\n\n"
180
+ f"Respond ONLY in this format:\n"
181
+ f"quality_a: <number>\n"
182
+ f"quality_b: <number>\n"
183
+ f"precision: <number>\n"
184
+ f"missing: <what A missed, or 'nothing'>\n"
185
+ f"reasoning: <one sentence>"
186
+ )
187
+
188
+ response = llm.generate(prompt, system="Output only the scores in the specified format.", max_tokens=200)
189
+
190
+ # Parse scores
191
+ qa = _parse_score(response, "quality_a")
192
+ qb = _parse_score(response, "quality_b")
193
+ prec = _parse_score(response, "precision")
194
+ missing_match = re.search(r"missing:\s*(.+?)(?:\n|$)", response, re.IGNORECASE)
195
+ reasoning_match = re.search(r"reasoning:\s*(.+?)(?:\n|$)", response, re.IGNORECASE)
196
+
197
+ results.append({
198
+ "precision": prec,
199
+ "quality_a": qa,
200
+ "quality_b": qb,
201
+ "missing": missing_match.group(1).strip() if missing_match else "",
202
+ "judge_reasoning": reasoning_match.group(1).strip() if reasoning_match else "",
203
+ })
204
+ except Exception as e:
205
+ logger.debug("Precision scoring failed for q%d: %s", i, e)
206
+ # Fallback: simple length-based heuristic
207
+ len_a = len(answer_a)
208
+ len_b = len(answer_b)
209
+ ratio = min(len_a, len_b) / max(len_a, len_b) if max(len_a, len_b) > 0 else 0
210
+ results.append({
211
+ "precision": round(ratio * 10, 1),
212
+ "quality_a": 5 if answer_a else 0,
213
+ "quality_b": 5 if answer_b else 0,
214
+ "missing": "",
215
+ "judge_reasoning": "LLM judge unavailable — estimated from answer length",
216
+ })
217
+
218
+ return results
219
+
220
+
221
+ def _parse_score(text: str, field: str) -> float:
222
+ """Extract a numeric score from LLM judge output."""
223
+ import re
224
+ match = re.search(rf"{field}:\s*([\d.]+)", text, re.IGNORECASE)
225
+ if match:
226
+ return min(10.0, max(0.0, float(match.group(1))))
227
+ return 5.0 # default if not found
228
+
229
+
230
+ def _build_full_dump(nodes) -> str:
231
+ """Build a full text dump of all graph nodes (baseline context)."""
232
+ parts = []
233
+ for node in nodes:
234
+ props = node.properties if hasattr(node, "properties") else {}
235
+ label = node.label if hasattr(node, "label") else ""
236
+ name = props.get("name") or props.get("title") or ""
237
+ content = props.get("content") or props.get("description") or props.get("statement") or ""
238
+ if name or content:
239
+ parts.append(f"[{label}] {name}\n{content}")
240
+ return "\n\n---\n\n".join(parts)
241
+
242
+
243
+ def _generate_questions(nodes) -> List[str]:
244
+ """Auto-generate relevant questions from graph content."""
245
+ labels = set()
246
+ names = []
247
+ for node in nodes:
248
+ label = node.label if hasattr(node, "label") else ""
249
+ props = node.properties if hasattr(node, "properties") else {}
250
+ if label:
251
+ labels.add(label)
252
+ name = props.get("name") or props.get("title") or ""
253
+ if name and len(names) < 5:
254
+ names.append((label, name))
255
+
256
+ questions = []
257
+ if labels:
258
+ top_label = max(labels, key=lambda l: sum(1 for n in nodes if getattr(n, "label", "") == l))
259
+ questions.append(f"What {top_label.lower()}s exist in this project?")
260
+ if names:
261
+ questions.append(f"Tell me about {names[0][1]}")
262
+ if len(names) > 1:
263
+ questions.append(f"How does {names[0][1]} relate to {names[1][1]}?")
264
+ questions.append("What are the key findings or decisions?")
265
+ questions.append("Summarize the most important information")
266
+ return questions[:5]
267
+
268
+
269
+ def _run_path_a(db, graph_name: str, question: str, llm) -> Dict[str, Any]:
270
+ """Path A: WITH AIContextDB — targeted retrieval then answer."""
271
+ start = time.monotonic()
272
+
273
+ # Use hybrid retrieval (same as rag_query tool)
274
+ from contextsynapse.search.rag import hybrid_retrieve
275
+ top, sources = hybrid_retrieve(db, question, graph_name, k=5)
276
+
277
+ # Build targeted context from top results only
278
+ context_parts = []
279
+ for r in top:
280
+ props = r.get("props", {})
281
+ content = props.get("content") or props.get("description") or props.get("statement") or props.get("name", "")
282
+ if content:
283
+ context_parts.append(content[:500])
284
+ context = "\n\n".join(context_parts)
285
+
286
+ # Count tokens for the targeted context
287
+ prompt = f"Context:\n{context}\n\nQuestion: {question}\n\nAnswer concisely."
288
+ prompt_tokens = len(prompt) // 4
289
+
290
+ # Generate answer
291
+ try:
292
+ answer = llm.generate(prompt, system="Answer based on the provided context.", max_tokens=500)
293
+ except Exception:
294
+ answer = "(LLM unavailable)"
295
+ answer_tokens = len(answer) // 4
296
+ total_tokens = prompt_tokens + answer_tokens
297
+
298
+ latency = int((time.monotonic() - start) * 1000)
299
+
300
+ return {
301
+ "tokens": total_tokens,
302
+ "prompt_tokens": prompt_tokens,
303
+ "answer_tokens": answer_tokens,
304
+ "context_chars": len(context),
305
+ "sources": len(sources),
306
+ "latency_ms": latency,
307
+ "cost": total_tokens / 1_000_000 * 2.50,
308
+ "answer": answer[:200],
309
+ }
310
+
311
+
312
+ def _run_path_b(full_dump: str, question: str, llm) -> Dict[str, Any]:
313
+ """Path B: WITHOUT AIContextDB — full dump then answer."""
314
+ start = time.monotonic()
315
+
316
+ # Send EVERYTHING to the LLM (no retrieval — brute force)
317
+ prompt = f"Context:\n{full_dump}\n\nQuestion: {question}\n\nAnswer concisely."
318
+ prompt_tokens = len(prompt) // 4
319
+
320
+ try:
321
+ answer = llm.generate(prompt, system="Answer based on the provided context.", max_tokens=500)
322
+ except Exception:
323
+ answer = "(LLM unavailable)"
324
+ answer_tokens = len(answer) // 4
325
+ total_tokens = prompt_tokens + answer_tokens
326
+
327
+ latency = int((time.monotonic() - start) * 1000)
328
+
329
+ return {
330
+ "tokens": total_tokens,
331
+ "prompt_tokens": prompt_tokens,
332
+ "answer_tokens": answer_tokens,
333
+ "context_chars": len(full_dump),
334
+ "sources": 0, # no retrieval — everything sent
335
+ "latency_ms": latency,
336
+ "cost": total_tokens / 1_000_000 * 2.50,
337
+ "answer": answer[:200],
338
+ }