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,986 @@
1
+ """
2
+ AIContextDB MCP Server
3
+ ==================
4
+ Exposes AIContextDB's Universal Tool Layer as MCP tools that any
5
+ MCP-compatible agent (Claude Code, Copilot, etc.) can use.
6
+
7
+ Two agents using this server share the SAME graph — that's the point.
8
+
9
+ Run directly:
10
+ python -m contextsynapse.mcp.server
11
+ python -m contextsynapse.mcp.server --namespace myproject
12
+ python -m contextsynapse.mcp.server --transport sse --port 8100
13
+
14
+ Or register with Claude Code:
15
+ claude mcp add contextcore -- python -m contextsynapse.mcp.server
16
+ """
17
+
18
+ import json
19
+ import logging
20
+ import os
21
+ import sys
22
+ import builtins
23
+
24
+ # ── CRITICAL: Protect stdout from stray print() calls ──────────────
25
+ # MCP uses stdout exclusively for JSON-RPC. Any print() from any module
26
+ # (logging, indexing, etc.) corrupts the protocol and crashes the server.
27
+ # Override builtins.print to redirect to stderr.
28
+ _original_print = builtins.print
29
+
30
+ def _safe_print(*args, **kwargs):
31
+ """Redirect all print() to stderr to protect MCP's stdout."""
32
+ kwargs['file'] = kwargs.get('file', sys.stderr)
33
+ if kwargs['file'] is sys.stdout:
34
+ kwargs['file'] = sys.stderr
35
+ _original_print(*args, **kwargs)
36
+
37
+ builtins.print = _safe_print
38
+
39
+ # ── CRITICAL: Force ALL logging to stderr BEFORE any imports ────────
40
+ # Replace stdout with a stderr wrapper so even modules that add
41
+ # StreamHandler(sys.stdout) end up writing to stderr.
42
+ _real_stdout = sys.stdout
43
+ sys.stdout = sys.stderr # Temporarily redirect stdout to stderr for imports
44
+
45
+ from mcp.server.fastmcp import FastMCP
46
+
47
+ # Restore real stdout for MCP transport
48
+ sys.stdout = _real_stdout
49
+
50
+ # Configure logging to stderr
51
+ logging.basicConfig(
52
+ level=logging.INFO,
53
+ format="%(asctime)s [contextcore-mcp] %(message)s",
54
+ stream=sys.stderr,
55
+ force=True,
56
+ )
57
+ # Force ALL existing and future handlers to stderr
58
+ for handler in logging.root.handlers[:]:
59
+ if hasattr(handler, 'stream'):
60
+ handler.stream = sys.stderr
61
+
62
+ # Monkey-patch StreamHandler to always use stderr
63
+ _OrigStreamHandler = logging.StreamHandler
64
+ class _StderrStreamHandler(_OrigStreamHandler):
65
+ def __init__(self, stream=None):
66
+ super().__init__(sys.stderr)
67
+ logging.StreamHandler = _StderrStreamHandler
68
+
69
+ logger = logging.getLogger(__name__)
70
+
71
+ # ── Lazy-loaded shared state ─────────────────────────────────────────
72
+ _conn = None # AIContextDBConnection singleton
73
+ _agent_name = os.environ.get("CONTEXTSYNAPSE_AGENT_NAME") or os.environ.get("AICONTEXTDB_AGENT_NAME", "unknown")
74
+ _agent_id = None
75
+ _api_key = None
76
+ _registry = None
77
+ _resolved_session = None
78
+ _thread_id = None
79
+ _tool_context = None # ToolContext for dispatch
80
+
81
+
82
+ def _get_registry():
83
+ global _registry
84
+ if _registry is None:
85
+ from contextsynapse.context.store_factory import create_agent_registry
86
+ _registry = create_agent_registry()
87
+ return _registry
88
+
89
+
90
+ def _ensure_registered():
91
+ global _agent_id, _api_key
92
+ if _agent_id and _api_key:
93
+ return _agent_id, _api_key
94
+ try:
95
+ from datetime import datetime, timezone
96
+ registry = _get_registry()
97
+ agent, api_key = registry.register(
98
+ name=_agent_name, role="agent", platform="desktop",
99
+ capabilities=["read", "write"],
100
+ metadata={"adapter": "mcp", "registered_at": datetime.now(timezone.utc).isoformat()},
101
+ )
102
+ _agent_id = agent.agent_id
103
+ _api_key = api_key
104
+ logger.info(f"MCP agent registered: {_agent_name} (id: {_agent_id})")
105
+ except Exception as e:
106
+ logger.warning(f"Agent registration failed: {e}")
107
+ _agent_id = _agent_name
108
+ _api_key = ""
109
+ return _agent_id, _api_key
110
+
111
+
112
+ def _get_conn():
113
+ global _conn, _thread_id
114
+
115
+ # Multi-session mode: check ContextVar first
116
+ from .session_context import get_session_scope
117
+ scope = get_session_scope()
118
+ if scope is not None:
119
+ if scope.conn is not None:
120
+ return scope.conn
121
+ # Build connection for this session scope
122
+ conn = _build_conn_for_namespace(scope.graph_namespace)
123
+ if conn:
124
+ conn._fan_out_graphs = scope.fan_out_graphs
125
+ scope.conn = conn
126
+ return conn
127
+
128
+ # Stdio single-session mode: use module globals (backward compat)
129
+ if _conn is None:
130
+ project_root = os.environ.get(
131
+ "AICONTEXTDB_PROJECT_ROOT",
132
+ os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")),
133
+ )
134
+ if project_root not in sys.path:
135
+ sys.path.insert(0, project_root)
136
+
137
+ if _resolved_session:
138
+ namespace = _resolved_session.graph_namespace
139
+ _thread_id = _resolved_session.thread_id
140
+ else:
141
+ namespace = os.environ.get("CONTEXTSYNAPSE_NAMESPACE") or os.environ.get("AICONTEXTDB_NAMESPACE", "default")
142
+
143
+ # Use Redis-backed connection if Redis URL is available
144
+ redis_url = os.environ.get("CONTEXTSYNAPSE_REDIS_URL") or os.environ.get("AICONTEXTDB_REDIS_URL")
145
+ if redis_url:
146
+ try:
147
+ from contextsynapse.core.registry import GraphRegistry
148
+ reg = GraphRegistry()
149
+ db = reg.get_graph(namespace, load_if_missing=True)
150
+ if db:
151
+ # Wrap the AIContextDB instance as an AIContextDBConnection
152
+ from contextsynapse.adapters._base import AIContextDBConnection
153
+ _conn = AIContextDBConnection(namespace=namespace)
154
+ # Override the connection's db with the Redis-backed one
155
+ _conn.db = db
156
+ _conn._namespace = namespace
157
+ # Set up executor for AIQL queries
158
+ try:
159
+ from contextsynapse.aiql import AIQLExecutor
160
+ _conn.executor = AIQLExecutor(contextcore=db)
161
+ except Exception:
162
+ pass
163
+ logger.info(f"Connected via Redis registry (namespace: {namespace}, "
164
+ f"nodes: {len(db.get_all_nodes())})")
165
+ else:
166
+ logger.warning(f"Graph '{namespace}' not in Redis registry, falling back to file")
167
+ from contextsynapse.adapters._base import AIContextDBConnection
168
+ _conn = AIContextDBConnection(namespace=namespace)
169
+ except Exception as e:
170
+ logger.warning(f"Redis connection failed: {e}, falling back to file")
171
+ from contextsynapse.adapters._base import AIContextDBConnection
172
+ _conn = AIContextDBConnection(namespace=namespace)
173
+ else:
174
+ from contextsynapse.adapters._base import AIContextDBConnection
175
+ daemon_url = os.environ.get("CONTEXTSYNAPSE_DAEMON_URL") or os.environ.get("AICONTEXTDB_DAEMON_URL")
176
+ _conn = AIContextDBConnection(namespace=namespace, daemon_url=daemon_url)
177
+
178
+ # Attach fan-out search capability for session-based connections
179
+ if _conn and _resolved_session:
180
+ _setup_fan_out(_conn, _resolved_session.session_id)
181
+ elif _conn:
182
+ # Namespace mode — check if this namespace is a session's runtime graph
183
+ _setup_fan_out_by_namespace(_conn, namespace)
184
+
185
+ if not _resolved_session:
186
+ _ensure_registered()
187
+ logger.info(f"AIContextDB connection ready (namespace: {namespace}, agent: {_agent_name})")
188
+ return _conn
189
+
190
+
191
+ def _build_conn_for_namespace(namespace: str):
192
+ """Build an AIContextDBConnection for a given namespace. Used by both single and multi-session modes."""
193
+ redis_url = os.environ.get("CONTEXTSYNAPSE_REDIS_URL") or os.environ.get("AICONTEXTDB_REDIS_URL")
194
+ if redis_url:
195
+ try:
196
+ from contextsynapse.core.registry import GraphRegistry
197
+ reg = GraphRegistry()
198
+ db = reg.get_graph(namespace, load_if_missing=True)
199
+ if db:
200
+ from contextsynapse.adapters._base import AIContextDBConnection
201
+ conn = AIContextDBConnection(namespace=namespace)
202
+ conn.db = db
203
+ conn._namespace = namespace
204
+ try:
205
+ from contextsynapse.aiql import AIQLExecutor
206
+ conn.executor = AIQLExecutor(contextcore=db)
207
+ except Exception:
208
+ pass
209
+ return conn
210
+ except Exception:
211
+ pass
212
+ from contextsynapse.adapters._base import AIContextDBConnection
213
+ return AIContextDBConnection(namespace=namespace)
214
+
215
+
216
+ def _setup_fan_out(conn, session_id: str):
217
+ """Attach fan-out search to a connection so it searches across attached graphs."""
218
+ try:
219
+ from contextsynapse.context.session import ContextSessionManager
220
+ from contextsynapse.core.registry import GraphRegistry
221
+
222
+ sm = ContextSessionManager(graph_registry=GraphRegistry())
223
+ attached = sm.get_attached_contexts(session_id)
224
+ if not attached:
225
+ return
226
+
227
+ extra_dbs = []
228
+ reg = GraphRegistry()
229
+ for ctx_ref in attached:
230
+ ctx_ns = ctx_ref.get("graph_namespace", "")
231
+ if ctx_ns:
232
+ ctx_db = reg.get_graph(ctx_ns, load_if_missing=True)
233
+ if ctx_db:
234
+ extra_dbs.append((ctx_ns, ctx_db))
235
+ logger.info(f"Fan-out: attached graph '{ctx_ns}' ({ctx_ref.get('name', '?')})")
236
+
237
+ if extra_dbs:
238
+ conn._fan_out_graphs = extra_dbs
239
+ except Exception as e:
240
+ logger.debug(f"Fan-out setup failed: {e}")
241
+
242
+
243
+ def _setup_fan_out_by_namespace(conn, namespace: str):
244
+ """For namespace mode: check if any session uses this graph and attach fan-out."""
245
+ try:
246
+ from contextsynapse.context.session import ContextSessionManager
247
+ from contextsynapse.core.registry import GraphRegistry
248
+
249
+ sm = ContextSessionManager(graph_registry=GraphRegistry())
250
+ # Find session that uses this namespace as runtime graph
251
+ for session in sm.list_sessions():
252
+ if session.graph_namespace == namespace:
253
+ _setup_fan_out(conn, session.session_id)
254
+ return
255
+ except Exception:
256
+ pass
257
+
258
+
259
+ def _get_tool_context():
260
+ """Build or return the ToolContext for dispatching tools."""
261
+ global _tool_context
262
+ from contextsynapse.tools import ToolContext
263
+
264
+ # Multi-session mode: build context from session scope
265
+ from .session_context import get_session_scope
266
+ scope = get_session_scope()
267
+ if scope is not None:
268
+ if scope.tool_context is not None:
269
+ return scope.tool_context
270
+ conn = _get_conn() # Will use scope.conn via context var
271
+ # Build runtime connection for agent-produced work
272
+ rt_ns = scope.runtime_namespace or f"{scope.graph_namespace}_rt"
273
+ if scope.runtime_conn is None:
274
+ scope.runtime_conn = _build_conn_for_namespace(rt_ns)
275
+ ctx = ToolContext(
276
+ conn=conn,
277
+ runtime_conn=scope.runtime_conn,
278
+ agent_id=scope.agent_id or "unknown",
279
+ agent_name=scope.agent_name,
280
+ thread_id=scope.thread_id or "",
281
+ )
282
+ ctx._access_level = scope.access_level
283
+ # Attach project — tasks/findings go to the runtime graph, not the atomic context
284
+ try:
285
+ from contextsynapse.project.graph import ProjectGraph
286
+ ctx.project = ProjectGraph(rt_ns, connection=scope.runtime_conn)
287
+ except Exception:
288
+ pass
289
+ scope.tool_context = ctx
290
+ return ctx
291
+
292
+ # Stdio single-session mode: use module globals
293
+ conn = _get_conn()
294
+
295
+ # Build runtime connection for agent-produced work
296
+ base_ns = conn.namespace if hasattr(conn, 'namespace') else (
297
+ getattr(conn, '_namespace', '') or 'default')
298
+ rt_ns = f"{base_ns}_rt"
299
+ if _resolved_session and getattr(_resolved_session, 'runtime_namespace', ''):
300
+ rt_ns = _resolved_session.runtime_namespace
301
+ rt_conn = _build_conn_for_namespace(rt_ns)
302
+
303
+ _tool_context = ToolContext(
304
+ conn=conn,
305
+ runtime_conn=rt_conn,
306
+ agent_id=_agent_id or "unknown",
307
+ agent_name=_agent_name,
308
+ thread_id=_thread_id or "",
309
+ )
310
+
311
+ # Attach project — tasks/findings go to the runtime graph, not the atomic context
312
+ try:
313
+ from contextsynapse.project.team_tools import get_project
314
+ _tool_context.project = get_project()
315
+ except Exception:
316
+ try:
317
+ from contextsynapse.project.graph import ProjectGraph
318
+ _tool_context.project = ProjectGraph(rt_ns, connection=rt_conn)
319
+ except Exception:
320
+ pass
321
+
322
+ return _tool_context
323
+
324
+
325
+ _DEFAULT_BASE_PATH = "contextcore_data"
326
+
327
+
328
+ # Valid edge labels for spec traceability (module-level so tests can import them)
329
+ _VALID_TRACE_LABELS: frozenset = frozenset([
330
+ "IMPLEMENTED_BY", "VERIFIED_BY", "COVERS", "REFINES", "CONSTRAINED_BY",
331
+ "PRESERVES", "STRANGLES", "REPLACES",
332
+ ])
333
+
334
+
335
+ def _load_code_context(project_name: str):
336
+ """Load a CodeContext instance for the given project name.
337
+
338
+ Returns None if the project cannot be found or loaded.
339
+ Used by the spec-driven MCP tools.
340
+ """
341
+ try:
342
+ from contextsynapse.project.code_context import CodeContext
343
+ return CodeContext.load(project_name)
344
+ except Exception:
345
+ return None
346
+
347
+
348
+ def _warmup_embedding() -> None:
349
+ """Start embedding model warmup in a background daemon thread.
350
+
351
+ Ollama loads the model on first embed_text() call (3-5s). By triggering
352
+ get_session_vector_store() at server startup in a daemon thread, the model
353
+ is already warm when the first agent calls orient().
354
+ """
355
+ import threading as _threading
356
+
357
+ def _do_warmup():
358
+ try:
359
+ from contextsynapse.context.vector_integration import get_session_vector_store
360
+ get_session_vector_store()
361
+ except Exception:
362
+ pass # warmup is best-effort — never crash the server
363
+
364
+ t = _threading.Thread(target=_do_warmup, daemon=True)
365
+ t.start()
366
+
367
+
368
+ # =====================================================================
369
+ # MCP Server Definition
370
+ # =====================================================================
371
+
372
+ def _auto_capture_fn(tool_name, params, result, ctx):
373
+ """Auto-capture tool call for conversation tracking."""
374
+ try:
375
+ from contextsynapse.agents.auto_capture import capture_tool_call
376
+ capture_tool_call(
377
+ agent_name=ctx.agent_name if hasattr(ctx, 'agent_name') else _agent_name,
378
+ agent_id=ctx.agent_id if hasattr(ctx, 'agent_id') else (_agent_id or "unknown"),
379
+ tool_name=tool_name,
380
+ params=params,
381
+ result=str(result)[:200],
382
+ namespace=ctx.conn._namespace if hasattr(ctx.conn, '_namespace') else "",
383
+ )
384
+ except Exception:
385
+ pass # Never let capture errors break tool execution
386
+
387
+
388
+ def _make_mcp_wrapper(tool_def):
389
+ """Create a wrapper function with EXPLICIT named parameters for FastMCP.
390
+
391
+ FastMCP inspects function signatures to generate tool schemas.
392
+ Using **kwargs produces a single 'kwargs' parameter in the schema,
393
+ which breaks everything. Instead, we dynamically create a function
394
+ with the exact parameter names the tool expects.
395
+ """
396
+ from contextsynapse.tools import ToolRegistry
397
+ import inspect
398
+
399
+ tool_name = tool_def.name
400
+ params = tool_def.params
401
+
402
+ if len(params) == 0:
403
+ def wrapper() -> str:
404
+ ctx = _get_tool_context()
405
+ return ToolRegistry.dispatch(tool_name, ctx, {})
406
+ wrapper.__name__ = tool_name
407
+ wrapper.__doc__ = tool_def.description
408
+ return wrapper
409
+
410
+ # Build a wrapper with explicit parameter names using exec
411
+ # This is the only way to create a function with dynamic parameter names
412
+ # that FastMCP can inspect via signature introspection.
413
+ param_parts = []
414
+ for p in params:
415
+ default = '""' if not p.required else None
416
+ if hasattr(p, 'default') and p.default not in (None, type(None)):
417
+ from contextsynapse.tools.registry import _MISSING
418
+ if p.default is not _MISSING:
419
+ default = repr(str(p.default))
420
+ if default is not None:
421
+ param_parts.append(f'{p.name}: str = {default}')
422
+ else:
423
+ param_parts.append(f'{p.name}: str')
424
+
425
+ param_str = ", ".join(param_parts)
426
+ param_names = [p.name for p in params]
427
+ dict_build = ", ".join(f'"{p}": {p}' for p in param_names)
428
+
429
+ # Write tools require write access
430
+ _WRITE_TOOLS = {"add_knowledge", "add_decision", "add_task", "add_relationship",
431
+ "complete_task", "claim_task", "handoff_task", "log_action",
432
+ "remember", "update_memory", "dispatch_goal", "init_project",
433
+ "ws_write_file", "ws_commit", "ws_push"}
434
+ is_write = tool_name in _WRITE_TOOLS
435
+
436
+ func_code = f'''
437
+ def {tool_name}({param_str}) -> str:
438
+ """{tool_def.description}"""
439
+ ctx = _get_tool_context()
440
+ # Write-access control
441
+ if {is_write} and hasattr(ctx, "_access_level") and ctx._access_level == "read":
442
+ return "Error: Read-only access. You do not have write permission for this session."
443
+ params = {{{dict_build}}}
444
+ # Remove empty optional params
445
+ params = {{k: v for k, v in params.items() if v != ""}}
446
+ result = ToolRegistry.dispatch("{tool_name}", ctx, params)
447
+ # Auto-capture agent activity
448
+ _auto_capture("{tool_name}", params, result, ctx)
449
+ return result
450
+ '''
451
+
452
+ local_ns = {
453
+ '_get_tool_context': _get_tool_context,
454
+ 'ToolRegistry': ToolRegistry,
455
+ '_auto_capture': _auto_capture_fn,
456
+ }
457
+ exec(func_code, local_ns)
458
+ wrapper = local_ns[tool_name]
459
+ return wrapper
460
+
461
+
462
+ def create_mcp_server() -> FastMCP:
463
+ """Create and return the AIContextDB MCP server with all tools.
464
+
465
+ Tools are loaded from the Universal Tool Registry (contextcore/tools/).
466
+ No inline tool definitions — everything comes from one source.
467
+ """
468
+ # Import tools to trigger registration
469
+ import contextsynapse.tools # noqa: F401
470
+ from contextsynapse.tools import ToolRegistry
471
+
472
+ mcp = FastMCP(
473
+ "contextsynapse",
474
+ instructions=(
475
+ "AIContextDB is a shared graph database for AI agent collaboration. "
476
+ "You have tools to: add knowledge nodes, search nodes, create relationships, "
477
+ "build LLM context, and manage tasks. "
478
+ "START HERE: Call orient() first to see what data exists, your tasks, and team status. "
479
+ "Use the high-level tools (add_knowledge, search_nodes, claim_task, complete_task) "
480
+ "for most work. Use query_graph only for advanced queries. "
481
+ "Everything you write is visible to other agents."
482
+ ),
483
+ )
484
+
485
+ # Warm up the embedding model in the background so first orient() is fast
486
+ _warmup_embedding()
487
+
488
+ # Register ALL tools from the Universal Tool Registry
489
+ for tool_def in ToolRegistry.all():
490
+ wrapper = _make_mcp_wrapper(tool_def)
491
+ mcp.add_tool(wrapper, name=tool_def.name, description=tool_def.description)
492
+
493
+ logger.info(f"MCP server created with {ToolRegistry.count()} tools from Universal Registry")
494
+
495
+ # ── MCP-only extras (not in universal registry) ─────────────────
496
+
497
+ # Extraction tools (MCP-only for now — depend on LLM client)
498
+ @mcp.tool()
499
+ def extract_entities(text: str, provider: str = "", model: str = "") -> str:
500
+ """Extract named entities from text using LLM."""
501
+ conn = _get_conn()
502
+ try:
503
+ from contextsynapse.extraction import extract_engine
504
+ result = extract_engine.extract_entities(
505
+ text, conn=conn, provider=provider or None, model=model or None,
506
+ )
507
+ return json.dumps(result, indent=2, default=str)[:3000]
508
+ except Exception as e:
509
+ return f"Error: {e}"
510
+
511
+ @mcp.tool()
512
+ def extract_facts(text: str, provider: str = "", model: str = "") -> str:
513
+ """Extract facts/claims from text using LLM."""
514
+ conn = _get_conn()
515
+ try:
516
+ from contextsynapse.extraction import extract_engine
517
+ result = extract_engine.extract_facts(
518
+ text, conn=conn, provider=provider or None, model=model or None,
519
+ )
520
+ return json.dumps(result, indent=2, default=str)[:3000]
521
+ except Exception as e:
522
+ return f"Error: {e}"
523
+
524
+ @mcp.tool()
525
+ def extract_with_schema(text: str, schema_path: str, provider: str = "", model: str = "") -> str:
526
+ """Extract entities using a YAML schema file."""
527
+ conn = _get_conn()
528
+ try:
529
+ from contextsynapse.extraction import extract_engine
530
+ result = extract_engine.extract_with_schema(
531
+ text, schema_path=schema_path, conn=conn,
532
+ provider=provider or None, model=model or None,
533
+ )
534
+ return json.dumps(result, indent=2, default=str)[:3000]
535
+ except Exception as e:
536
+ return f"Error: {e}"
537
+
538
+ @mcp.tool()
539
+ def save_schema(schema_path: str) -> str:
540
+ """Upload a YAML schema to the registry."""
541
+ conn = _get_conn()
542
+ try:
543
+ from contextsynapse.extraction import extract_engine
544
+ result = extract_engine.save_schema(schema_path, conn=conn)
545
+ return result
546
+ except Exception as e:
547
+ return f"Error: {e}"
548
+
549
+ @mcp.tool()
550
+ def list_schemas() -> str:
551
+ """List all saved schemas in the registry."""
552
+ conn = _get_conn()
553
+ try:
554
+ from contextsynapse.extraction import extract_engine
555
+ result = extract_engine.list_schemas(conn=conn)
556
+ return result
557
+ except Exception as e:
558
+ return f"Error: {e}"
559
+
560
+ @mcp.tool()
561
+ def extract_with_saved_schema(text: str, schema_name: str, provider: str = "", model: str = "") -> str:
562
+ """Extract entities using a schema from the registry."""
563
+ conn = _get_conn()
564
+ try:
565
+ from contextsynapse.extraction import extract_engine
566
+ result = extract_engine.extract_with_saved_schema(
567
+ text, schema_name=schema_name, conn=conn,
568
+ provider=provider or None, model=model or None,
569
+ )
570
+ return json.dumps(result, indent=2, default=str)[:3000]
571
+ except Exception as e:
572
+ return f"Error: {e}"
573
+
574
+ # Project tools (SDLC context namespaces)
575
+ @mcp.tool()
576
+ def create_project(name: str) -> str:
577
+ """Create an SDLC context project namespace."""
578
+ if not name:
579
+ return "Error: name is required."
580
+ try:
581
+ from contextsynapse.project.project_context import ProjectContext
582
+ pc = ProjectContext.create(name, base_path=_DEFAULT_BASE_PATH)
583
+ return f"Project '{pc.name}' created. Use coverage_score to check context coverage."
584
+ except Exception as e:
585
+ return f"Error: {e}"
586
+
587
+ @mcp.tool()
588
+ def add_sdlc_node(
589
+ project_name: str,
590
+ node_type: str,
591
+ node_id: str,
592
+ properties: str = "{}",
593
+ ) -> str:
594
+ """Add a typed SDLC artifact node to a project namespace.
595
+
596
+ Args:
597
+ project_name: the project namespace name (must exist)
598
+ node_type: one of the 15 SDLC types — Requirement, UserStory, Goal,
599
+ ArchDecision, Pattern, Constraint, CodeModule, APIContract,
600
+ DataModel, TestCase, TestResult, KnownIssue,
601
+ Preservation, Migration, ChangeRecord
602
+ node_id: unique node identifier within the project (e.g. "req:auth-login")
603
+ properties: JSON object of node properties (must include required fields
604
+ for the node_type — check validate_node for details)
605
+ """
606
+ if not project_name:
607
+ return "Error: project_name is required."
608
+ if not node_type:
609
+ return "Error: node_type is required."
610
+ if not node_id:
611
+ return "Error: node_id is required."
612
+ try:
613
+ import json as _json
614
+ from contextsynapse.project.project_context import ProjectContext
615
+ from contextsynapse.project.sdlc_schema import is_sdlc_node_type, validate_node, ALL_NODE_TYPES
616
+ from contextsynapse.core.graph_structures import GraphNode
617
+
618
+ if not is_sdlc_node_type(node_type):
619
+ return (
620
+ f"Error: '{node_type}' is not a valid SDLC node type. "
621
+ f"Valid types: {', '.join(ALL_NODE_TYPES)}"
622
+ )
623
+
624
+ try:
625
+ props = _json.loads(properties) if properties else {}
626
+ except _json.JSONDecodeError as exc:
627
+ return f"Error: properties is not valid JSON — {exc}"
628
+
629
+ missing = validate_node(node_type, props)
630
+ if missing:
631
+ return (
632
+ f"Error: node_type '{node_type}' is missing required fields: "
633
+ f"{', '.join(missing)}"
634
+ )
635
+
636
+ pc = ProjectContext.load(project_name, base_path=_DEFAULT_BASE_PATH)
637
+ existing = pc.db.get_node(node_id)
638
+ if existing is not None:
639
+ return _json.dumps({
640
+ "ok": False,
641
+ "error": "conflict",
642
+ "node_id": node_id,
643
+ "existing_label": existing.label,
644
+ "hint": "Use a different node_id or update the existing node.",
645
+ })
646
+ pc.db.add_node(GraphNode(id=node_id, label=node_type, properties=props))
647
+ return _json.dumps({"ok": True, "node_id": node_id, "node_type": node_type})
648
+ except KeyError as e:
649
+ return f"Error: {e}"
650
+ except Exception as e:
651
+ return f"Error: {e}"
652
+
653
+ @mcp.tool()
654
+ def coverage_score(project_name: str) -> str:
655
+ """Return per-layer SDLC coverage scores for a project namespace."""
656
+ if not project_name:
657
+ return "Error: project_name is required."
658
+ try:
659
+ from contextsynapse.project.project_context import ProjectContext
660
+ pc = ProjectContext.load(project_name, base_path=_DEFAULT_BASE_PATH)
661
+ return json.dumps(pc.coverage_score())
662
+ except Exception as e:
663
+ return f"Error: {e}"
664
+
665
+ @mcp.tool()
666
+ def project_stale(project_name: str) -> str:
667
+ """Return all stale SDLC nodes in a project namespace."""
668
+ if not project_name:
669
+ return "Error: project_name is required."
670
+ try:
671
+ from contextsynapse.project.project_context import ProjectContext
672
+ pc = ProjectContext.load(project_name, base_path=_DEFAULT_BASE_PATH)
673
+ return json.dumps(pc.stale_report())
674
+ except Exception as e:
675
+ return f"Error: {e}"
676
+
677
+ @mcp.tool()
678
+ def agent_brief(project_name: str, topic: str = "", phase: str = "") -> str:
679
+ """Return a scoped SDLC context package for an agent about to work.
680
+
681
+ Args:
682
+ project_name: the project namespace name
683
+ topic: keyword to filter nodes by (case-insensitive substring match)
684
+ phase: SDLC layer to filter to (intent/design/build/verify/evolution)
685
+ """
686
+ if not project_name:
687
+ return "Error: project_name is required."
688
+ try:
689
+ from contextsynapse.project.project_context import ProjectContext
690
+ pc = ProjectContext.load(project_name, base_path=_DEFAULT_BASE_PATH)
691
+ return json.dumps(pc.agent_brief(topic=topic, phase=phase))
692
+ except Exception as e:
693
+ return f"Error: {e}"
694
+
695
+ @mcp.tool()
696
+ def add_sdlc_edge(
697
+ project_name: str,
698
+ edge_type: str,
699
+ source_id: str,
700
+ target_id: str,
701
+ ) -> str:
702
+ """Declare a typed relationship between two SDLC nodes in a project namespace.
703
+
704
+ Args:
705
+ project_name: the project namespace name (must exist)
706
+ edge_type: one of the 12 SDLC edge types —
707
+ IMPLEMENTS, SATISFIES, TESTS, GOVERNS, CONSTRAINED_BY,
708
+ DEPENDS_ON, EXPOSES, USES,
709
+ PRESERVES, STRANGLES, REPLACES, MODIFIES
710
+ source_id: node_id of the source node (must exist in the project)
711
+ target_id: node_id of the target node (must exist in the project)
712
+
713
+ The edge is validated against the schema: each edge_type has a required
714
+ source label and target label. Both nodes must already exist.
715
+ """
716
+ if not project_name:
717
+ return "Error: project_name is required."
718
+ if not edge_type:
719
+ return "Error: edge_type is required."
720
+ if not source_id:
721
+ return "Error: source_id is required."
722
+ if not target_id:
723
+ return "Error: target_id is required."
724
+ try:
725
+ import uuid as _uuid
726
+ from contextsynapse.project.project_context import ProjectContext
727
+ from contextsynapse.project.sdlc_schema import SDLC_EDGE_TYPES
728
+ from contextsynapse.core.graph_structures import GraphEdge
729
+
730
+ if edge_type not in SDLC_EDGE_TYPES:
731
+ return (
732
+ f"Error: '{edge_type}' is not a valid SDLC edge type. "
733
+ f"Valid types: {', '.join(sorted(SDLC_EDGE_TYPES))}"
734
+ )
735
+
736
+ expected_src_label, expected_tgt_label = SDLC_EDGE_TYPES[edge_type]
737
+
738
+ pc = ProjectContext.load(project_name, base_path=_DEFAULT_BASE_PATH)
739
+
740
+ src_node = pc.db.get_node(source_id)
741
+ if src_node is None:
742
+ return f"Error: source node '{source_id}' not found in project '{project_name}'."
743
+ if src_node.label != expected_src_label:
744
+ return (
745
+ f"Error: edge type '{edge_type}' requires source label "
746
+ f"'{expected_src_label}', but '{source_id}' has label '{src_node.label}'."
747
+ )
748
+
749
+ tgt_node = pc.db.get_node(target_id)
750
+ if tgt_node is None:
751
+ return f"Error: target node '{target_id}' not found in project '{project_name}'."
752
+ if tgt_node.label != expected_tgt_label:
753
+ return (
754
+ f"Error: edge type '{edge_type}' requires target label "
755
+ f"'{expected_tgt_label}', but '{target_id}' has label '{tgt_node.label}'."
756
+ )
757
+
758
+ edge_id = str(_uuid.uuid4())
759
+ pc.db.add_edge(GraphEdge(
760
+ id=edge_id,
761
+ source=source_id,
762
+ target=target_id,
763
+ label=edge_type,
764
+ ))
765
+ return json.dumps({
766
+ "ok": True,
767
+ "edge_id": edge_id,
768
+ "edge_type": edge_type,
769
+ "source_id": source_id,
770
+ "target_id": target_id,
771
+ })
772
+ except KeyError as e:
773
+ return f"Error: {e}"
774
+ except Exception as e:
775
+ return f"Error: {e}"
776
+
777
+ @mcp.tool()
778
+ def search_sdlc(
779
+ project_name: str,
780
+ query: str,
781
+ layer: str = "",
782
+ limit: int = 20,
783
+ ) -> str:
784
+ """Search SDLC nodes in a project namespace by keyword relevance.
785
+
786
+ Args:
787
+ project_name: the project namespace name (must exist)
788
+ query: space-separated keywords to search for
789
+ layer: optional SDLC layer to restrict results to —
790
+ intent, design, build, verify, or evolution
791
+ limit: max results to return (default 20, max 100)
792
+
793
+ Returns JSON list of {node_id, label, layer, score, snippet} ordered
794
+ by relevance. 'layer' tells you which SDLC phase each result belongs to
795
+ so agents can reason about coverage gaps.
796
+ """
797
+ if not project_name:
798
+ return "Error: project_name is required."
799
+ if not query:
800
+ return "Error: query is required."
801
+ try:
802
+ from contextsynapse.project.project_context import ProjectContext
803
+ pc = ProjectContext.load(project_name, base_path=_DEFAULT_BASE_PATH)
804
+ results = pc.search(query=query, layer=layer, limit=min(limit, 100))
805
+ return json.dumps(results)
806
+ except (KeyError, ValueError) as e:
807
+ return f"Error: {e}"
808
+ except Exception as e:
809
+ return f"Error: {e}"
810
+
811
+ # Spec-driven traceability tools
812
+ @mcp.tool()
813
+ def ingest_spec(project_name: str, markdown_text: str) -> str:
814
+ """Parse a markdown requirements spec and write Requirement/Feature/Constraint nodes.
815
+
816
+ Returns JSON with the list of created node IDs and count.
817
+ """
818
+ cc = _load_code_context(project_name)
819
+ if cc is None:
820
+ return json.dumps({"error": f"Project '{project_name}' not found"})
821
+ ids = cc.ingest_spec(markdown_text)
822
+ return json.dumps({"created": ids, "count": len(ids)})
823
+
824
+ @mcp.tool()
825
+ def get_requirements(project_name: str) -> str:
826
+ """Return all Requirement nodes for a project as JSON."""
827
+ cc = _load_code_context(project_name)
828
+ if cc is None:
829
+ return json.dumps({"error": f"Project '{project_name}' not found"})
830
+ reqs = cc.get_requirements()
831
+ return json.dumps(reqs, default=str)
832
+
833
+ @mcp.tool()
834
+ def check_coverage(project_name: str) -> str:
835
+ """Analyse requirement traceability coverage for a project.
836
+
837
+ Returns JSON with keys: covered, partial, uncovered, coverage_pct, total.
838
+ """
839
+ cc = _load_code_context(project_name)
840
+ if cc is None:
841
+ return json.dumps({"error": f"Project '{project_name}' not found"})
842
+ return json.dumps(cc.check_coverage())
843
+
844
+ @mcp.tool()
845
+ def link_artifact(
846
+ project_name: str, req_id: str, artifact_id: str, edge_label: str
847
+ ) -> str:
848
+ """Create a traceability edge between a requirement and an artifact.
849
+
850
+ edge_label must be one of: IMPLEMENTED_BY, VERIFIED_BY, COVERS, REFINES, CONSTRAINED_BY.
851
+ """
852
+ if edge_label not in _VALID_TRACE_LABELS:
853
+ return json.dumps({"error": f"Invalid edge label '{edge_label}'. "
854
+ f"Must be one of: {sorted(_VALID_TRACE_LABELS)}"})
855
+ cc = _load_code_context(project_name)
856
+ if cc is None:
857
+ return json.dumps({"error": f"Project '{project_name}' not found"})
858
+ cc.link_artifact(req_id, artifact_id, edge_label)
859
+ return json.dumps({"ok": True, "edge": f"{req_id} --{edge_label}--> {artifact_id}"})
860
+
861
+ # Pipeline tool
862
+ @mcp.tool()
863
+ def run_pipeline(prompt: str, session_id: str = "", max_turns: int = 10) -> str:
864
+ """Run a multi-agent pipeline on a session."""
865
+ return "Pipeline execution is available via the dashboard. Use the REST API to trigger it."
866
+
867
+ # Resource
868
+ @mcp.resource("contextcore://summary")
869
+ def resource_summary() -> str:
870
+ """Current graph summary."""
871
+ ctx = _get_tool_context()
872
+ from contextsynapse.tools import ToolRegistry
873
+ return ToolRegistry.dispatch("graph_summary", ctx, {})
874
+
875
+ return mcp
876
+
877
+
878
+ # =====================================================================
879
+ # Entry point
880
+ # =====================================================================
881
+
882
+
883
+ def create_multi_session_app(graph_registry=None):
884
+ """Create a Starlette app that serves MCP for multiple sessions.
885
+
886
+ Each session is accessed via /sessions/{session_id}/sse (or /messages).
887
+ Authentication happens per-connection via Bearer token.
888
+
889
+ Mount on the main FastAPI app:
890
+ app.mount("/mcp", create_multi_session_app(graph_registry))
891
+ """
892
+ from .auth_middleware import MCPAuthMiddleware
893
+
894
+ server = create_mcp_server()
895
+
896
+ # Get the SSE Starlette app from FastMCP
897
+ try:
898
+ sse_app = server.sse_app()
899
+ except Exception:
900
+ # Fallback: use streamable_http_app if available
901
+ try:
902
+ sse_app = server.streamable_http_app()
903
+ except Exception:
904
+ logger.error("[MCP] Failed to create SSE/HTTP app from FastMCP")
905
+ from starlette.applications import Starlette
906
+ return Starlette()
907
+
908
+ # Wrap with auth middleware
909
+ app = MCPAuthMiddleware(sse_app, graph_registry=graph_registry)
910
+
911
+ logger.info("[MCP] Multi-session app created (auth + session routing)")
912
+ return app
913
+
914
+
915
+ def main():
916
+ """Run the AIContextDB MCP server."""
917
+ import argparse
918
+
919
+ parser = argparse.ArgumentParser(description="AIContextDB MCP Server")
920
+ parser.add_argument("--session", default=None, help="Session ID to connect to")
921
+ parser.add_argument("--api-key", default=None, help="Agent API key (agent_id:secret)")
922
+ parser.add_argument("--namespace", default="default", help="Direct namespace (legacy)")
923
+ parser.add_argument("--agent-name", default=None, help="Agent display name")
924
+ parser.add_argument("--transport", default="stdio", choices=["stdio", "sse", "streamable-http"],
925
+ help="Transport: stdio (local), sse (remote), streamable-http (remote)")
926
+ parser.add_argument("--port", default=8100, type=int, help="Port for SSE/HTTP transport")
927
+ args = parser.parse_args()
928
+
929
+ global _agent_id, _api_key, _agent_name, _resolved_session
930
+
931
+ api_key = args.api_key or os.environ.get("CONTEXTSYNAPSE_API_KEY") or os.environ.get("AICONTEXTDB_API_KEY", "")
932
+ session_id = args.session or os.environ.get("CONTEXTSYNAPSE_SESSION_ID") or os.environ.get("AICONTEXTDB_SESSION_ID", os.environ.get("AICONTEXTDB_SESSION", ""))
933
+
934
+ if args.agent_name:
935
+ _agent_name = args.agent_name
936
+
937
+ # Session-based connection (preferred)
938
+ if session_id and api_key:
939
+ try:
940
+ from contextsynapse.context.session_resolver import resolve_session
941
+ resolved = resolve_session(session_id, api_key)
942
+ _resolved_session = resolved
943
+ _agent_id = resolved.agent_id
944
+ _agent_name = resolved.agent_name
945
+ _api_key = api_key.split(":", 1)[1] if ":" in api_key else ""
946
+ logger.info(f"Session resolved: {session_id} -> graph={resolved.graph_namespace}, "
947
+ f"goal='{resolved.goal}', access={resolved.access_level}")
948
+ except Exception as e:
949
+ # Retry once after 2s — Redis may not be ready on cold start
950
+ logger.warning(f"Session resolution attempt 1 failed: {e}, retrying...")
951
+ import time
952
+ time.sleep(2)
953
+ try:
954
+ resolved = resolve_session(session_id, api_key)
955
+ _resolved_session = resolved
956
+ _agent_id = resolved.agent_id
957
+ _agent_name = resolved.agent_name
958
+ _api_key = api_key.split(":", 1)[1] if ":" in api_key else ""
959
+ logger.info(f"Session resolved (retry): {session_id} -> graph={resolved.graph_namespace}")
960
+ except Exception as e2:
961
+ logger.error(f"Session resolution failed after retry: {e2}")
962
+ # Fall back to namespace mode instead of exiting
963
+ logger.info("Falling back to namespace mode: default")
964
+ os.environ["AICONTEXTDB_NAMESPACE"] = args.namespace
965
+ elif api_key:
966
+ if ":" in api_key:
967
+ _agent_id, _api_key = api_key.split(":", 1)
968
+ os.environ["AICONTEXTDB_NAMESPACE"] = args.namespace
969
+ logger.info(f"Starting in namespace mode: {args.namespace}")
970
+ else:
971
+ os.environ["AICONTEXTDB_NAMESPACE"] = args.namespace
972
+ logger.info(f"Starting in dev mode (no auth): {args.namespace}")
973
+
974
+ server = create_mcp_server()
975
+
976
+ if args.transport in ("sse", "streamable-http"):
977
+ os.environ["FASTMCP_PORT"] = str(args.port)
978
+ os.environ["FASTMCP_HOST"] = "0.0.0.0"
979
+ logger.info(f"MCP server starting on port {args.port} ({args.transport})")
980
+ logger.info(f"Remote agents can connect to: http://0.0.0.0:{args.port}/mcp")
981
+
982
+ server.run(transport=args.transport)
983
+
984
+
985
+ if __name__ == "__main__":
986
+ main()