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,1028 @@
1
+ """Intelligence API Router — manage collection plans, hierarchy, watchdog.
2
+
3
+ Endpoints:
4
+ GET /intelligence/plans — List all collection plans
5
+ GET /intelligence/plans/{name} — Get a plan's details + status
6
+ POST /intelligence/plans — Create/update a collection plan
7
+ DELETE /intelligence/plans/{name} — Delete a plan
8
+ POST /intelligence/plans/{name}/run — Run all pipelines for a plan NOW
9
+ POST /intelligence/plans/{name}/run/{pipeline} — Run one pipeline
10
+
11
+ GET /intelligence/hierarchy — Get signal hierarchy
12
+ POST /intelligence/hierarchy/link — Add a link
13
+ POST /intelligence/hierarchy/lateral — Add a lateral link
14
+
15
+ GET /intelligence/watchdog/status — Watchdog status + recent alerts
16
+ POST /intelligence/watchdog/start — Start watchdog
17
+ POST /intelligence/watchdog/stop — Stop watchdog
18
+ POST /intelligence/watchdog/check — Run one watchdog check cycle
19
+
20
+ GET /intelligence/signals — Recent signals + propagation log
21
+ GET /intelligence/impact — Impact tracker stats + training data
22
+ """
23
+ from __future__ import annotations
24
+
25
+ import logging
26
+ from typing import Any, Dict
27
+
28
+ from fastapi import APIRouter, Body, Depends, HTTPException, Query
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ def create_intelligence_router(
34
+ context_manager,
35
+ graph_registry=None,
36
+ user_auth=None,
37
+ ):
38
+ """Create the intelligence API router with injected dependencies."""
39
+
40
+ router = APIRouter(prefix="/intelligence", tags=["intelligence"])
41
+
42
+ # Lazy-init singletons
43
+ _collector = None
44
+ _hierarchy = None
45
+ _reactive = None
46
+ _watchdog = None
47
+ _impact_tracker = None
48
+ _persistence = None
49
+
50
+ def _get_persistence():
51
+ nonlocal _persistence
52
+ if _persistence is None:
53
+ from ..intelligence.persistence import IntelligencePersistence
54
+ _persistence = IntelligencePersistence(context_manager)
55
+ return _persistence
56
+
57
+ _rate_limiter_instance = None
58
+ _health_monitor_instance = None
59
+
60
+ def _get_rate_limiter():
61
+ nonlocal _rate_limiter_instance
62
+ if _rate_limiter_instance is None:
63
+ from ..intelligence.rate_limiter import PipelineRateLimiter
64
+ _rate_limiter_instance = PipelineRateLimiter()
65
+ return _rate_limiter_instance
66
+
67
+ def _get_health_monitor():
68
+ nonlocal _health_monitor_instance
69
+ if _health_monitor_instance is None:
70
+ from ..intelligence.pipeline_health import PipelineHealthMonitor
71
+ _health_monitor_instance = PipelineHealthMonitor(
72
+ alert_dispatcher=_get_alert_dispatcher(),
73
+ )
74
+ return _health_monitor_instance
75
+
76
+ def _get_collector():
77
+ nonlocal _collector
78
+ if _collector is None:
79
+ from ..intelligence.collector import ContextCollector
80
+ _collector = ContextCollector(
81
+ rate_limiter=_get_rate_limiter(),
82
+ health_monitor=_get_health_monitor(),
83
+ )
84
+ # Load persisted plans
85
+ store = _get_persistence()
86
+ for plan in store.load_all_plans():
87
+ _collector.register(plan)
88
+ logger.info("[INTEL-API] Loaded %d collection plans", len(_collector.list_plans()))
89
+ return _collector
90
+
91
+ def _get_hierarchy():
92
+ nonlocal _hierarchy
93
+ if _hierarchy is None:
94
+ store = _get_persistence()
95
+ _hierarchy = store.load_hierarchy()
96
+ if not _hierarchy:
97
+ from ..intelligence.signal_hierarchy import SignalHierarchy
98
+ _hierarchy = SignalHierarchy()
99
+ return _hierarchy
100
+
101
+ def _get_reactive():
102
+ nonlocal _reactive
103
+ if _reactive is None:
104
+ from ..intelligence.reactive import ReactiveController
105
+ _reactive = ReactiveController(alert_dispatcher=_get_alert_dispatcher())
106
+ store = _get_persistence()
107
+ if not store.load_reactive_rules(_reactive):
108
+ _reactive.add_default_rules()
109
+ return _reactive
110
+
111
+ def _get_watchdog():
112
+ nonlocal _watchdog
113
+ if _watchdog is None:
114
+ from ..intelligence.watchdog import BreakingNewsWatchdog
115
+ from ..intelligence.impact_tracker import ImpactTracker
116
+ _watchdog = BreakingNewsWatchdog(
117
+ hierarchy=_get_hierarchy(),
118
+ collector=_get_collector(),
119
+ reactive=_get_reactive(),
120
+ impact_tracker=_get_impact_tracker(),
121
+ )
122
+ store = _get_persistence()
123
+ store.load_watchdog_config(_watchdog)
124
+ return _watchdog
125
+
126
+ def _get_impact_tracker():
127
+ nonlocal _impact_tracker
128
+ if _impact_tracker is None:
129
+ from ..intelligence.impact_tracker import ImpactTracker
130
+ _impact_tracker = ImpactTracker()
131
+ return _impact_tracker
132
+
133
+ # ═══════════════════════════════════════════════════════════════
134
+ # COLLECTION PLANS
135
+ # ═══════════════════════════════════════════════════════════════
136
+
137
+ @router.get("/plans")
138
+ async def list_plans():
139
+ """List all registered collection plans."""
140
+ collector = _get_collector()
141
+ plans = []
142
+ for name in collector.list_plans():
143
+ plan = collector.get_plan(name)
144
+ status = collector.status(name)
145
+ plans.append({
146
+ "name": name,
147
+ "description": plan.context_description,
148
+ "tags": plan.tags,
149
+ "template": plan.template,
150
+ "pipeline_count": len(plan.pipelines),
151
+ "status": status,
152
+ })
153
+ return {"plans": plans, "count": len(plans)}
154
+
155
+ @router.get("/plans/{name}")
156
+ async def get_plan(name: str):
157
+ """Get a collection plan's details and pipeline status."""
158
+ collector = _get_collector()
159
+ plan = collector.get_plan(name)
160
+ if not plan:
161
+ raise HTTPException(404, f"Plan '{name}' not found")
162
+ return {
163
+ "plan": plan.to_dict(),
164
+ "status": collector.status(name),
165
+ }
166
+
167
+ @router.post("/plans")
168
+ async def create_plan(body: dict = Body(...)):
169
+ """Create or update a collection plan.
170
+
171
+ Body:
172
+ {
173
+ "context_name": "TCS Intelligence",
174
+ "context_description": "Track TCS...",
175
+ "tags": ["tcs", "it-services"],
176
+ "template": "market_analysis",
177
+ "pipelines": [
178
+ {
179
+ "name": "news",
180
+ "source_type": "rss",
181
+ "sources": ["https://..."],
182
+ "interval": "30m",
183
+ "strategy": "news_article",
184
+ "filter": {
185
+ "topics": ["TCS", "Tata Consultancy"],
186
+ "exclude": ["cricket"],
187
+ "semantic_query": "TCS business performance"
188
+ }
189
+ }
190
+ ]
191
+ }
192
+ """
193
+ from ..intelligence.collector import CollectionPlan
194
+ try:
195
+ plan = CollectionPlan.from_dict(body)
196
+ except Exception as exc:
197
+ raise HTTPException(400, f"Invalid plan: {exc}")
198
+
199
+ collector = _get_collector()
200
+ collector.register(plan)
201
+
202
+ # Persist
203
+ store = _get_persistence()
204
+ store.save_collection_plan(plan)
205
+
206
+ return {
207
+ "status": "created",
208
+ "name": plan.context_name,
209
+ "pipelines": len(plan.pipelines),
210
+ }
211
+
212
+ @router.delete("/plans/{name}")
213
+ async def delete_plan(name: str):
214
+ """Remove a collection plan."""
215
+ collector = _get_collector()
216
+ if name not in collector.list_plans():
217
+ raise HTTPException(404, f"Plan '{name}' not found")
218
+ del collector._plans[name]
219
+ return {"status": "deleted", "name": name}
220
+
221
+ @router.post("/plans/{name}/run")
222
+ async def run_plan(name: str):
223
+ """Run all pipelines for a plan immediately."""
224
+ collector = _get_collector()
225
+ plan = collector.get_plan(name)
226
+ if not plan:
227
+ raise HTTPException(404, f"Plan '{name}' not found")
228
+
229
+ result = collector.run_all(name)
230
+ return result.to_dict()
231
+
232
+ @router.post("/plans/{name}/run/{pipeline}")
233
+ async def run_pipeline(name: str, pipeline: str):
234
+ """Run a single pipeline within a plan."""
235
+ collector = _get_collector()
236
+ plan = collector.get_plan(name)
237
+ if not plan:
238
+ raise HTTPException(404, f"Plan '{name}' not found")
239
+
240
+ result = collector.run_pipeline(name, pipeline)
241
+ return result
242
+
243
+ # ═══════════════════════════════════════════════════════════════
244
+ # SIGNAL HIERARCHY
245
+ # ═══════════════════════════════════════════════════════════════
246
+
247
+ @router.get("/hierarchy")
248
+ async def get_hierarchy():
249
+ """Get the signal hierarchy."""
250
+ h = _get_hierarchy()
251
+ return {
252
+ "hierarchy": h.to_dict(),
253
+ "context_count": len(h._context_levels),
254
+ "link_count": len(h._links),
255
+ }
256
+
257
+ @router.post("/hierarchy/link")
258
+ async def add_hierarchy_link(body: dict = Body(...)):
259
+ """Add a hierarchical link (upstream → downstream).
260
+
261
+ Body: {"upstream": "Global Macro", "downstream": "India Economy",
262
+ "relationship": "macro_affects", "weight": 0.8}
263
+ """
264
+ from ..intelligence.signal_hierarchy import ContextLink
265
+ h = _get_hierarchy()
266
+ link = ContextLink.from_dict(body)
267
+ h.add_link(link)
268
+
269
+ store = _get_persistence()
270
+ store.save_hierarchy(h)
271
+
272
+ return {"status": "added", "link": link.to_dict()}
273
+
274
+ @router.post("/hierarchy/lateral")
275
+ async def add_lateral_link(body: dict = Body(...)):
276
+ """Add a lateral link (peer ↔ peer).
277
+
278
+ Body: {"upstream": "TCS", "downstream": "Infosys",
279
+ "relationship": "competes_with", "weight": 0.7}
280
+ """
281
+ from ..intelligence.signal_hierarchy import ContextLink
282
+ h = _get_hierarchy()
283
+ link = ContextLink.from_dict(body)
284
+ h.add_lateral_link(link)
285
+
286
+ store = _get_persistence()
287
+ store.save_hierarchy(h)
288
+
289
+ return {"status": "added", "link": link.to_dict()}
290
+
291
+ @router.post("/hierarchy/level")
292
+ async def set_level(body: dict = Body(...)):
293
+ """Set hierarchy level for a context.
294
+
295
+ Body: {"context": "TCS", "level": "company"}
296
+ """
297
+ h = _get_hierarchy()
298
+ h.set_level(body["context"], body["level"])
299
+
300
+ store = _get_persistence()
301
+ store.save_hierarchy(h)
302
+
303
+ return {"status": "set", "context": body["context"], "level": body["level"]}
304
+
305
+ @router.get("/hierarchy/chain/{context}")
306
+ async def get_chain(context: str):
307
+ """Get upstream + downstream + lateral connections for a context."""
308
+ h = _get_hierarchy()
309
+ return h.get_all_connected(context)
310
+
311
+ # ═══════════════════════════════════════════════════════════════
312
+ # WATCHDOG
313
+ # ═══════════════════════════════════════════════════════════════
314
+
315
+ @router.get("/watchdog/status")
316
+ async def watchdog_status():
317
+ """Get watchdog status and recent alerts."""
318
+ wd = _get_watchdog()
319
+ return {
320
+ "running": wd._running,
321
+ "sources": [{"url": s.url, "name": s.name} for s in wd._sources],
322
+ "recent_alerts": wd.get_alert_log(limit=20),
323
+ }
324
+
325
+ @router.post("/watchdog/start")
326
+ async def watchdog_start(interval: int = Query(60)):
327
+ """Start the watchdog background loop."""
328
+ wd = _get_watchdog()
329
+ wd.start(interval_seconds=interval)
330
+ return {"status": "started", "interval_seconds": interval}
331
+
332
+ @router.post("/watchdog/stop")
333
+ async def watchdog_stop():
334
+ """Stop the watchdog."""
335
+ wd = _get_watchdog()
336
+ wd.stop()
337
+ return {"status": "stopped"}
338
+
339
+ @router.post("/watchdog/check")
340
+ async def watchdog_check():
341
+ """Run one watchdog check cycle immediately."""
342
+ wd = _get_watchdog()
343
+ result = wd.check()
344
+ return result.to_dict()
345
+
346
+ @router.post("/watchdog/source")
347
+ async def add_watchdog_source(body: dict = Body(...)):
348
+ """Add a source to the watchdog.
349
+
350
+ Body: {"url": "https://feeds.reuters.com/...", "name": "Reuters"}
351
+ """
352
+ wd = _get_watchdog()
353
+ wd.add_source(
354
+ url=body["url"],
355
+ name=body.get("name", ""),
356
+ source_type=body.get("source_type", "rss"),
357
+ )
358
+ store = _get_persistence()
359
+ store.save_watchdog_config(wd)
360
+ return {"status": "added", "source": body["url"]}
361
+
362
+ # ═══════════════════════════════════════════════════════════════
363
+ # SIGNALS + IMPACT
364
+ # ═══════════════════════════════════════════════════════════════
365
+
366
+ @router.get("/signals")
367
+ async def get_signals(limit: int = Query(50)):
368
+ """Get recent propagated signals."""
369
+ h = _get_hierarchy()
370
+ reactive = _get_reactive()
371
+ return {
372
+ "propagation_log": h.get_propagation_log(limit),
373
+ "reaction_log": reactive.get_reaction_log(limit),
374
+ "active_escalations": reactive.get_escalations(),
375
+ }
376
+
377
+ @router.get("/impact")
378
+ async def get_impact():
379
+ """Get impact tracker stats and training data."""
380
+ tracker = _get_impact_tracker()
381
+ return {
382
+ "link_stats": tracker.get_link_stats(),
383
+ "training_data_count": len(tracker.get_training_data()),
384
+ "training_sample": tracker.get_training_data()[:10],
385
+ }
386
+
387
+ @router.post("/impact/outcome")
388
+ async def record_outcome(body: dict = Body(...)):
389
+ """Record an actual outcome for a predicted signal.
390
+
391
+ Body: {"signal_id": "...", "target_context": "TCS",
392
+ "actual_impact": 0.45, "metric": "stock_price_change_pct",
393
+ "observed_value": -2.3}
394
+ """
395
+ tracker = _get_impact_tracker()
396
+ result = tracker.record_outcome(
397
+ signal_id=body["signal_id"],
398
+ target_context=body["target_context"],
399
+ actual_impact=body.get("actual_impact", 0.0),
400
+ metric=body.get("metric", ""),
401
+ observed_value=body.get("observed_value", 0.0),
402
+ )
403
+ if result is None:
404
+ raise HTTPException(404, "No matching prediction found")
405
+ return result
406
+
407
+ # ═══════════════════════════════════════════════════════════════
408
+ # TRACK — one-call entity tracking
409
+ # ═══════════════════════════════════════════════════════════════
410
+
411
+ _tracker = None
412
+
413
+ def _get_tracker():
414
+ nonlocal _tracker
415
+ if _tracker is None:
416
+ from ..intelligence.tracker import EntityTracker
417
+ _tracker = EntityTracker(
418
+ collector=_get_collector(),
419
+ hierarchy=_get_hierarchy(),
420
+ persistence=_get_persistence(),
421
+ )
422
+ return _tracker
423
+
424
+ @router.post("/track")
425
+ async def track_entity(body: dict = Body(...)):
426
+ """Start tracking an entity with one call.
427
+
428
+ Body: {"entity": "TCS", "template": "indian_listed_company",
429
+ "extra": {"bse_code": "532540", "full_name": "Tata Consultancy Services"}}
430
+ """
431
+ tracker = _get_tracker()
432
+ result = tracker.track(
433
+ entity_name=body["entity"],
434
+ template=body.get("template", "generic_topic"),
435
+ extra=body.get("extra"),
436
+ )
437
+ if "error" in result:
438
+ raise HTTPException(400, result["error"])
439
+ return result
440
+
441
+ @router.delete("/track/{entity}")
442
+ async def untrack_entity(entity: str):
443
+ """Stop tracking an entity."""
444
+ tracker = _get_tracker()
445
+ return tracker.untrack(entity)
446
+
447
+ @router.get("/track")
448
+ async def list_tracked():
449
+ """List all tracked entities."""
450
+ tracker = _get_tracker()
451
+ return {
452
+ "tracked": tracker.list_tracked(),
453
+ "templates": tracker.list_templates(),
454
+ }
455
+
456
+ # ═══════════════════════════════════════════════════════════════
457
+ # WEBHOOKS — push-based ingestion
458
+ # ═══════════════════════════════════════════════════════════════
459
+
460
+ _webhook_receiver = None
461
+
462
+ def _get_webhook_receiver():
463
+ nonlocal _webhook_receiver
464
+ if _webhook_receiver is None:
465
+ from ..intelligence.webhook_receiver import WebhookReceiver
466
+ _webhook_receiver = WebhookReceiver(db=None)
467
+ return _webhook_receiver
468
+
469
+ @router.post("/webhooks/register")
470
+ async def register_webhook(body: dict = Body(...)):
471
+ """Register a webhook endpoint.
472
+
473
+ Body: {"webhook_id": "tcs_news", "context_name": "TCS", "strategy": "news_article"}
474
+ Returns: {"webhook_id": "tcs_news", "endpoint": "/intelligence/webhooks/tcs_news", "secret": "..."}
475
+ """
476
+ receiver = _get_webhook_receiver()
477
+ config = receiver.register(
478
+ webhook_id=body["webhook_id"],
479
+ context_name=body["context_name"],
480
+ secret=body.get("secret", ""),
481
+ strategy=body.get("strategy", "news_article"),
482
+ )
483
+ return {
484
+ "webhook_id": config.webhook_id,
485
+ "endpoint": f"/intelligence/webhooks/{config.webhook_id}",
486
+ "secret": config.secret,
487
+ }
488
+
489
+ @router.get("/webhooks")
490
+ async def list_webhooks():
491
+ """List all registered webhooks."""
492
+ receiver = _get_webhook_receiver()
493
+ return {"webhooks": receiver.list_webhooks()}
494
+
495
+ @router.post("/webhooks/{webhook_id}")
496
+ async def receive_webhook(webhook_id: str, body: dict = Body(...)):
497
+ """Receive a webhook payload and ingest it.
498
+
499
+ Body: {"title": "...", "content": "...", "url": "...", "source": "..."}
500
+ """
501
+ receiver = _get_webhook_receiver()
502
+ result = receiver.receive(webhook_id, body)
503
+ if result.status == "error":
504
+ raise HTTPException(400, result.error)
505
+ return result.to_dict()
506
+
507
+ # ═══════════════════════════════════════════════════════════════
508
+ # ALERTS — notification channels
509
+ # ═══════════════════════════════════════════════════════════════
510
+
511
+ _alert_dispatcher = None
512
+
513
+ def _get_alert_dispatcher():
514
+ nonlocal _alert_dispatcher
515
+ if _alert_dispatcher is None:
516
+ from ..intelligence.alerts import AlertDispatcher, AlertChannel
517
+ _alert_dispatcher = AlertDispatcher()
518
+ # Default: log channel always active
519
+ _alert_dispatcher.add_channel(AlertChannel(
520
+ name="system_log", channel_type="log", min_severity="warning",
521
+ ))
522
+ return _alert_dispatcher
523
+
524
+ @router.post("/alerts/channel")
525
+ async def add_alert_channel(body: dict = Body(...)):
526
+ """Add a notification channel.
527
+
528
+ Body: {"name": "slack", "channel_type": "webhook",
529
+ "config": {"url": "https://hooks.slack.com/..."}, "min_severity": "warning"}
530
+ """
531
+ from ..intelligence.alerts import AlertChannel
532
+ dispatcher = _get_alert_dispatcher()
533
+ channel = AlertChannel.from_dict(body)
534
+ dispatcher.add_channel(channel)
535
+ return {"status": "added", "channel": channel.to_dict()}
536
+
537
+ @router.get("/alerts/channels")
538
+ async def list_alert_channels():
539
+ dispatcher = _get_alert_dispatcher()
540
+ return {"channels": dispatcher.list_channels()}
541
+
542
+ @router.get("/alerts/log")
543
+ async def get_alert_log(limit: int = Query(50)):
544
+ dispatcher = _get_alert_dispatcher()
545
+ return {"deliveries": dispatcher.get_delivery_log(limit)}
546
+
547
+ @router.post("/alerts/test")
548
+ async def test_alert(body: dict = Body(...)):
549
+ """Send a test alert to verify channels work.
550
+
551
+ Body: {"severity": "warning", "message": "Test alert"}
552
+ """
553
+ dispatcher = _get_alert_dispatcher()
554
+ results = dispatcher.dispatch(
555
+ signal_type="test",
556
+ entity_name="Test Entity",
557
+ context_name="Test Context",
558
+ severity=body.get("severity", "warning"),
559
+ details={"message": body.get("message", "Test alert from intelligence API")},
560
+ )
561
+ return {"results": [r.to_dict() for r in results]}
562
+
563
+ # ═══════════════════════════════════════════════════════════════
564
+ # BULK IMPORT — batch URL ingestion
565
+ # ═══════════════════════════════════════════════════════════════
566
+
567
+ @router.post("/bulk/ingest")
568
+ async def bulk_ingest(body: dict = Body(...)):
569
+ """Ingest multiple URLs into a context in one call.
570
+
571
+ Body: {
572
+ "context_name": "TCS Intelligence",
573
+ "urls": ["https://...", "https://...", ...],
574
+ "strategy": "news_article", # optional
575
+ }
576
+ """
577
+ context_name = body.get("context_name", "")
578
+ urls = body.get("urls", [])
579
+ strategy = body.get("strategy")
580
+
581
+ if not urls:
582
+ raise HTTPException(400, "No URLs provided")
583
+
584
+ from ..ingestion.smart_ingest import ingest_url
585
+ from ..ingestion.amplifier import build_context_purpose
586
+
587
+ # Get context purpose
588
+ collector = _get_collector()
589
+ plan = collector.get_plan(context_name)
590
+ context_purpose = ""
591
+ if plan:
592
+ context_purpose = build_context_purpose(
593
+ context_name=plan.context_name,
594
+ context_description=plan.context_description,
595
+ tags=plan.tags,
596
+ )
597
+
598
+ results = {
599
+ "total": len(urls),
600
+ "ingested": 0,
601
+ "deduped": 0,
602
+ "errors": 0,
603
+ "details": [],
604
+ }
605
+
606
+ for url in urls:
607
+ try:
608
+ # Get a db for the context namespace
609
+ if graph_registry:
610
+ ns = context_name.lower().replace(" ", "_") if context_name else "default"
611
+ db = graph_registry.get_graph(ns, load_if_missing=True)
612
+ if not db:
613
+ db = graph_registry.create_graph(ns)
614
+ else:
615
+ from ..core.registry import graph_registry as _gr
616
+ db = _gr.get_graph("default", load_if_missing=True)
617
+
618
+ r = ingest_url(
619
+ url, db,
620
+ strategy=strategy,
621
+ context_purpose=context_purpose,
622
+ )
623
+
624
+ if hasattr(r, 'errors') and r.errors:
625
+ if any("Duplicate" in str(e) for e in r.errors):
626
+ results["deduped"] += 1
627
+ results["details"].append({"url": url, "status": "deduped"})
628
+ else:
629
+ results["errors"] += 1
630
+ results["details"].append({"url": url, "status": "error", "error": str(r.errors)})
631
+ else:
632
+ results["ingested"] += 1
633
+ results["details"].append({
634
+ "url": url, "status": "ingested",
635
+ "entities": len(getattr(r, 'entity_ids', {})),
636
+ "facts": len(getattr(r, 'fact_ids', [])),
637
+ })
638
+
639
+ except Exception as exc:
640
+ results["errors"] += 1
641
+ results["details"].append({"url": url, "status": "error", "error": str(exc)})
642
+
643
+ return results
644
+
645
+ # ═══════════════════════════════════════════════════════════════
646
+ # TIME-SERIES — convenience temporal queries
647
+ # ═══════════════════════════════════════════════════════════════
648
+
649
+ @router.get("/timeseries/sentiment/{entity}")
650
+ async def sentiment_over_time(entity: str, days: int = Query(30), bucket: str = Query("day")):
651
+ """Get sentiment distribution over time for an entity."""
652
+ from ..intelligence.timeseries import TimeSeriesQuery
653
+ db = graph_registry.get_graph("default", load_if_missing=True) if graph_registry else None
654
+ ts = TimeSeriesQuery(db)
655
+ return {"entity": entity, "days": days, "data": ts.sentiment_over_time(entity, days, bucket)}
656
+
657
+ @router.get("/timeseries/compare")
658
+ async def compare_sentiment(entities: str = Query(...), days: int = Query(7)):
659
+ """Compare sentiment across entities. Comma-separated names."""
660
+ from ..intelligence.timeseries import TimeSeriesQuery
661
+ db = graph_registry.get_graph("default", load_if_missing=True) if graph_registry else None
662
+ ts = TimeSeriesQuery(db)
663
+ names = [e.strip() for e in entities.split(",")]
664
+ return ts.compare_sentiment(names, days)
665
+
666
+ @router.get("/timeseries/timeline/{entity}")
667
+ async def entity_timeline(entity: str, days: int = Query(30), limit: int = Query(50)):
668
+ """Get chronological timeline of events for an entity."""
669
+ from ..intelligence.timeseries import TimeSeriesQuery
670
+ db = graph_registry.get_graph("default", load_if_missing=True) if graph_registry else None
671
+ ts = TimeSeriesQuery(db)
672
+ return {"entity": entity, "events": ts.entity_timeline(entity, days, limit)}
673
+
674
+ @router.get("/timeseries/indicator/{name}")
675
+ async def indicator_over_time(name: str, days: int = Query(90)):
676
+ """Get indicator values over time."""
677
+ from ..intelligence.timeseries import TimeSeriesQuery
678
+ db = graph_registry.get_graph("default", load_if_missing=True) if graph_registry else None
679
+ ts = TimeSeriesQuery(db)
680
+ return {"indicator": name, "data": ts.indicator_over_time(name, days)}
681
+
682
+ # ═══════════════════════════════════════════════════════════════
683
+ # HEALTH — pipeline health monitoring
684
+ # ═══════════════════════════════════════════════════════════════
685
+
686
+ @router.get("/health")
687
+ async def pipeline_health(context: str = Query(""), pipeline: str = Query("")):
688
+ """Get pipeline health status."""
689
+ monitor = _get_health_monitor()
690
+ return {"health": monitor.get_health(context, pipeline)}
691
+
692
+ @router.get("/health/failing")
693
+ async def failing_pipelines():
694
+ """Get all failing pipelines."""
695
+ monitor = _get_health_monitor()
696
+ return {"failing": monitor.get_failing(), "degraded": monitor.get_degraded()}
697
+
698
+ # ═══════════════════════════════════════════════════════════════
699
+ # RATE LIMITING — per-source throttling
700
+ # ═══════════════════════════════════════════════════════════════
701
+
702
+ @router.get("/ratelimit/stats")
703
+ async def rate_limit_stats():
704
+ """Get rate limiting stats per domain."""
705
+ from ..intelligence.rate_limiter import PipelineRateLimiter
706
+ limiter = PipelineRateLimiter()
707
+ return {"stats": limiter.get_stats()}
708
+
709
+ # ═══════════════════════════════════════════════════════════════
710
+ # RUNTIME CONTEXT — cross-context assembly
711
+ # ═══════════════════════════════════════════════════════════════
712
+
713
+ _assembler = None
714
+
715
+ def _get_assembler():
716
+ nonlocal _assembler
717
+ if _assembler is None:
718
+ from ..intelligence.runtime_context import RuntimeContextAssembler
719
+ _assembler = RuntimeContextAssembler(
720
+ graph_registry=graph_registry,
721
+ context_manager=context_manager,
722
+ )
723
+ return _assembler
724
+
725
+ @router.post("/runtime/assemble")
726
+ async def assemble_runtime_context(body: dict = Body(...)):
727
+ """Assemble a runtime view across multiple atomic contexts.
728
+
729
+ Body: {
730
+ "contexts": ["TCS", "India Economy", "Banking Sector"],
731
+ "focus_entity": "TCS",
732
+ "days": 30
733
+ }
734
+ """
735
+ contexts = body.get("contexts", [])
736
+ if not contexts:
737
+ raise HTTPException(400, "No contexts specified")
738
+
739
+ assembler = _get_assembler()
740
+ view = assembler.assemble(
741
+ contexts=contexts,
742
+ focus_entity=body.get("focus_entity", ""),
743
+ days=body.get("days", 30),
744
+ )
745
+ return view.to_dict()
746
+
747
+ @router.get("/runtime/compare")
748
+ async def compare_contexts(contexts: str = Query(...), days: int = Query(30)):
749
+ """Quick comparison across contexts. Comma-separated names."""
750
+ assembler = _get_assembler()
751
+ names = [c.strip() for c in contexts.split(",")]
752
+ view = assembler.assemble(contexts=names, days=days)
753
+ return {
754
+ "contexts": names,
755
+ "sentiment_comparison": view.sentiment_comparison,
756
+ "cross_entity_pairs": view.cross_entity_pairs,
757
+ "stats": view.stats,
758
+ }
759
+
760
+ # ═══════════════════════════════════════════════════════════════
761
+ # SESSIONS — attach/detach contexts, insight write-back
762
+ # ═══════════════════════════════════════════════════════════════
763
+
764
+ _session_mgr = None
765
+
766
+ def _get_session_mgr():
767
+ nonlocal _session_mgr
768
+ if _session_mgr is None:
769
+ from ..intelligence.session import SessionManager
770
+ _session_mgr = SessionManager(
771
+ graph_registry=graph_registry,
772
+ context_manager=context_manager,
773
+ )
774
+ return _session_mgr
775
+
776
+ @router.post("/sessions")
777
+ async def create_session(body: dict = Body(...)):
778
+ """Create a new session.
779
+ Body: {"name": "IT Sector Analysis"}
780
+ """
781
+ mgr = _get_session_mgr()
782
+ session = mgr.create(body.get("name", "Untitled"))
783
+
784
+ # Auto-attach contexts if provided
785
+ for ctx in body.get("contexts", []):
786
+ session.attach(ctx)
787
+
788
+ return session.to_dict()
789
+
790
+ @router.get("/sessions")
791
+ async def list_sessions():
792
+ mgr = _get_session_mgr()
793
+ return {"sessions": mgr.list_sessions()}
794
+
795
+ @router.get("/sessions/{session_id}")
796
+ async def get_session(session_id: str):
797
+ mgr = _get_session_mgr()
798
+ session = mgr.get(session_id)
799
+ if not session:
800
+ raise HTTPException(404, "Session not found")
801
+ return session.to_dict()
802
+
803
+ @router.post("/sessions/{session_id}/attach")
804
+ async def attach_context(session_id: str, body: dict = Body(...)):
805
+ """Attach a context to a session.
806
+ Body: {"context": "tcs"}
807
+ """
808
+ mgr = _get_session_mgr()
809
+ session = mgr.get(session_id)
810
+ if not session:
811
+ raise HTTPException(404, "Session not found")
812
+ ctx = body.get("context", "")
813
+ if not ctx:
814
+ raise HTTPException(400, "No context specified")
815
+ session.attach(ctx)
816
+ return session.status()
817
+
818
+ @router.post("/sessions/{session_id}/detach")
819
+ async def detach_context(session_id: str, body: dict = Body(...)):
820
+ """Detach a context from a session.
821
+ Body: {"context": "tcs"}
822
+ """
823
+ mgr = _get_session_mgr()
824
+ session = mgr.get(session_id)
825
+ if not session:
826
+ raise HTTPException(404, "Session not found")
827
+ session.detach(body.get("context", ""))
828
+ return session.status()
829
+
830
+ @router.post("/sessions/{session_id}/assemble")
831
+ async def assemble_session(session_id: str, body: dict = Body({})):
832
+ """Assemble the runtime view for a session."""
833
+ mgr = _get_session_mgr()
834
+ session = mgr.get(session_id)
835
+ if not session:
836
+ raise HTTPException(404, "Session not found")
837
+ view = session.assemble(
838
+ focus_entity=body.get("focus_entity", ""),
839
+ days=body.get("days", 30),
840
+ )
841
+ if not view:
842
+ return {"error": "No contexts attached"}
843
+ return view.to_dict()
844
+
845
+ @router.post("/sessions/{session_id}/insight")
846
+ async def add_insight(session_id: str, body: dict = Body(...)):
847
+ """Write an insight back to a context (visible to all agents + dashboard).
848
+
849
+ Body: {"insight": "TCS outperforms when USD weakens",
850
+ "produced_by": "agent:claude", "confidence": 0.85,
851
+ "context": "tcs",
852
+ "evidence": ["TCS Q1 up 4.2%", "USD stable"]}
853
+
854
+ If context is specified, the insight is written INTO that context's
855
+ graph — visible in the dashboard, to other agents, and in runtime views.
856
+ If context is omitted, stored in session-only graph.
857
+ """
858
+ mgr = _get_session_mgr()
859
+ session = mgr.get(session_id)
860
+ if not session:
861
+ raise HTTPException(404, "Session not found")
862
+ ins = session.add_insight(
863
+ insight=body.get("insight", ""),
864
+ produced_by=body.get("produced_by", ""),
865
+ confidence=body.get("confidence", 0.0),
866
+ evidence=body.get("evidence", []),
867
+ tags=body.get("tags", []),
868
+ context=body.get("context", ""),
869
+ )
870
+ return ins.to_dict()
871
+
872
+ @router.get("/sessions/{session_id}/insights")
873
+ async def get_insights(session_id: str, produced_by: str = Query("")):
874
+ """Get insights from a session."""
875
+ mgr = _get_session_mgr()
876
+ session = mgr.get(session_id)
877
+ if not session:
878
+ raise HTTPException(404, "Session not found")
879
+ insights = session.get_insights(produced_by=produced_by)
880
+ return {"insights": [i.to_dict() for i in insights]}
881
+
882
+ @router.delete("/sessions/{session_id}")
883
+ async def delete_session(session_id: str):
884
+ mgr = _get_session_mgr()
885
+ if mgr.delete(session_id):
886
+ return {"status": "deleted"}
887
+ raise HTTPException(404, "Session not found")
888
+
889
+ # ── Prediction Tracker ──
890
+
891
+ def _get_predictor():
892
+ try:
893
+ from plugins.stock_analysis.predictor import PredictionTracker
894
+ return PredictionTracker(graph_registry=graph_registry)
895
+ except ImportError:
896
+ # Add project root to path and retry
897
+ import sys
898
+ from pathlib import Path
899
+ root = str(Path(__file__).parent.parent.parent)
900
+ if root not in sys.path:
901
+ sys.path.insert(0, root)
902
+ try:
903
+ from plugins.stock_analysis.predictor import PredictionTracker
904
+ return PredictionTracker(graph_registry=graph_registry)
905
+ except ImportError:
906
+ raise HTTPException(501, "Stock analysis plugin not installed")
907
+
908
+ @router.post("/predict/{entity}")
909
+ async def predict_entity(entity: str, horizon: str = Query("1d")):
910
+ """Make a directional prediction for an entity."""
911
+ try:
912
+ tracker = _get_predictor()
913
+ pred = tracker.predict(entity, horizon=horizon)
914
+ return pred.to_dict()
915
+ except HTTPException:
916
+ raise
917
+ except Exception as e:
918
+ logger.exception("Prediction error for %s", entity)
919
+ raise HTTPException(500, str(e))
920
+
921
+ @router.post("/predict")
922
+ async def predict_all(companies: list = Body(None)):
923
+ """Make predictions for all tracked companies."""
924
+ tracker = _get_predictor()
925
+ preds = tracker.predict_all(companies)
926
+ return {"predictions": [p.to_dict() for p in preds]}
927
+
928
+ @router.post("/predictions/verify")
929
+ async def verify_predictions():
930
+ """Verify past predictions against actual outcomes."""
931
+ tracker = _get_predictor()
932
+ verified = tracker.verify_predictions()
933
+ return {"verified": verified, "count": len(verified)}
934
+
935
+ @router.get("/predictions/test")
936
+ async def test_predictor():
937
+ """Test if predictor can be instantiated."""
938
+ try:
939
+ tracker = _get_predictor()
940
+ return {"status": "ok", "type": type(tracker).__name__}
941
+ except Exception as e:
942
+ return {"status": "error", "error": str(e), "type": type(e).__name__}
943
+
944
+ @router.get("/predictions/accuracy")
945
+ async def get_accuracy():
946
+ """Get prediction accuracy stats."""
947
+ try:
948
+ tracker = _get_predictor()
949
+ return tracker.get_accuracy()
950
+ except HTTPException:
951
+ raise
952
+ except Exception as e:
953
+ logger.exception("Prediction accuracy error")
954
+ raise HTTPException(500, str(e))
955
+
956
+ @router.get("/predictions")
957
+ async def list_predictions(entity: str = Query(""), verified_only: bool = Query(False)):
958
+ """List all predictions, optionally filtered."""
959
+ tracker = _get_predictor()
960
+ stats = tracker.get_accuracy()
961
+ preds = stats["predictions"]
962
+ if entity:
963
+ preds = [p for p in preds if p["entity"].lower() == entity.lower()]
964
+ if verified_only:
965
+ preds = [p for p in preds if p["verified"]]
966
+ return {"predictions": preds, "total": len(preds)}
967
+
968
+ # ── Signal Config ──
969
+
970
+ def _get_signal_config():
971
+ try:
972
+ import sys
973
+ from pathlib import Path
974
+ root = str(Path(__file__).parent.parent.parent)
975
+ if root not in sys.path:
976
+ sys.path.insert(0, root)
977
+ from plugins.stock_analysis.signal_config import SignalConfig
978
+ return SignalConfig()
979
+ except ImportError:
980
+ raise HTTPException(501, "Stock analysis plugin not installed")
981
+
982
+ @router.get("/signal-config/{entity}")
983
+ async def get_signal_config(entity: str):
984
+ """Get full signal config for an entity (weights, thresholds, decay, RL)."""
985
+ cfg = _get_signal_config()
986
+ return cfg.get_full_config(entity)
987
+
988
+ @router.get("/signal-config")
989
+ async def get_all_signal_configs():
990
+ """Get configs for all tracked stocks + defaults."""
991
+ cfg = _get_signal_config()
992
+ return {"configs": cfg.get_all_configs(), "defaults": cfg.get_defaults()}
993
+
994
+ @router.put("/signal-config/{entity}/weights")
995
+ async def set_signal_weights(entity: str, weights: dict = Body(...)):
996
+ """Set custom weights for a stock. Auto-normalized to sum=1."""
997
+ cfg = _get_signal_config()
998
+ cfg.set_weights(entity, weights)
999
+ return {"status": "updated", "weights": cfg.get_weights(entity)}
1000
+
1001
+ @router.put("/signal-config/{entity}/thresholds")
1002
+ async def set_signal_thresholds(entity: str, thresholds: dict = Body(...)):
1003
+ """Set custom thresholds for a stock."""
1004
+ cfg = _get_signal_config()
1005
+ cfg.set_thresholds(entity, thresholds)
1006
+ return {"status": "updated", "thresholds": cfg.get_thresholds(entity)}
1007
+
1008
+ @router.put("/signal-config/rl")
1009
+ async def set_rl_config(rl: dict = Body(...)):
1010
+ """Set RL parameters (reward, penalty, enabled)."""
1011
+ cfg = _get_signal_config()
1012
+ cfg.set_rl(rl)
1013
+ return {"status": "updated", "rl": cfg.get_rl()}
1014
+
1015
+ @router.delete("/signal-config/{entity}")
1016
+ async def reset_signal_config(entity: str):
1017
+ """Reset a stock's config to domain/global defaults."""
1018
+ cfg = _get_signal_config()
1019
+ cfg.reset(entity)
1020
+ return {"status": "reset", "config": cfg.get_full_config(entity)}
1021
+
1022
+ @router.get("/learned-weights")
1023
+ async def get_learned_weights():
1024
+ """Get RL-learned weights for all stocks."""
1025
+ tracker = _get_predictor()
1026
+ return tracker.get_weights()
1027
+
1028
+ return router