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,438 @@
1
+ """Signal Hierarchy — upstream/downstream context linking with event propagation.
2
+
3
+ Defines how contexts relate to each other in a hierarchy:
4
+ World → Geopolitical → Country → Market/Sector → Company
5
+
6
+ When an upstream context ingests a significant event, it propagates
7
+ downstream to all linked contexts. Downstream contexts can query
8
+ upstream for macro context.
9
+
10
+ Usage:
11
+ from contextsynapse.intelligence.signal_hierarchy import SignalHierarchy, ContextLink
12
+
13
+ hierarchy = SignalHierarchy()
14
+
15
+ # Define the hierarchy
16
+ hierarchy.add_link(ContextLink(upstream="Global Macro", downstream="India Economy", relationship="country_in"))
17
+ hierarchy.add_link(ContextLink(upstream="India Economy", downstream="IT Services Sector", relationship="sector_in"))
18
+ hierarchy.add_link(ContextLink(upstream="IT Services Sector", downstream="TCS Intelligence", relationship="company_in"))
19
+ hierarchy.add_link(ContextLink(upstream="IT Services Sector", downstream="Infosys Intelligence", relationship="company_in"))
20
+
21
+ # When Global Macro gets a signal, find all downstream contexts
22
+ affected = hierarchy.get_downstream("Global Macro")
23
+ # → ["India Economy", "IT Services Sector", "TCS Intelligence", "Infosys Intelligence"]
24
+
25
+ # When TCS needs macro context, find all upstream
26
+ context_chain = hierarchy.get_upstream("TCS Intelligence")
27
+ # → ["IT Services Sector", "India Economy", "Global Macro"]
28
+ """
29
+ from __future__ import annotations
30
+
31
+ import logging
32
+ from dataclasses import dataclass, field
33
+ from datetime import datetime, timezone
34
+ from typing import Any, Dict, List, Optional, Set
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+
39
+ # Standard hierarchy levels — defines the natural ordering
40
+ HIERARCHY_LEVELS = {
41
+ "world": 0,
42
+ "geopolitical": 1,
43
+ "country": 2,
44
+ "sector": 3,
45
+ "market": 3,
46
+ "supply_chain": 4,
47
+ "company": 5,
48
+ "product": 6,
49
+ }
50
+
51
+
52
+ @dataclass
53
+ class ContextLink:
54
+ """A directional link between two contexts in the signal hierarchy."""
55
+ upstream: str # context that produces signals
56
+ downstream: str # context that receives signals
57
+ relationship: str = "feeds" # how they relate: country_in, sector_in, company_in, supplies_to, competes_with
58
+ propagate_signals: List[str] = field(default_factory=lambda: ["sentiment_reversal", "threshold_breach"])
59
+ weight: float = 1.0 # propagation strength (0.0-1.0)
60
+
61
+ def to_dict(self) -> Dict[str, Any]:
62
+ return {
63
+ "upstream": self.upstream,
64
+ "downstream": self.downstream,
65
+ "relationship": self.relationship,
66
+ "propagate_signals": self.propagate_signals,
67
+ "weight": self.weight,
68
+ }
69
+
70
+ @classmethod
71
+ def from_dict(cls, data: Dict[str, Any]) -> "ContextLink":
72
+ return cls(
73
+ upstream=data.get("upstream", ""),
74
+ downstream=data.get("downstream", ""),
75
+ relationship=data.get("relationship", "feeds"),
76
+ propagate_signals=data.get("propagate_signals", ["sentiment_reversal", "threshold_breach"]),
77
+ weight=data.get("weight", 1.0),
78
+ )
79
+
80
+
81
+ @dataclass
82
+ class PropagatedSignal:
83
+ """A signal propagated from upstream to downstream context."""
84
+ original_signal_type: str
85
+ source_context: str
86
+ target_context: str
87
+ entity_name: str
88
+ relationship: str
89
+ hop_count: int # how many levels it traveled
90
+ weight: float # decayed weight (original * link_weight per hop)
91
+ details: Dict[str, Any] = field(default_factory=dict)
92
+ propagated_at: str = ""
93
+
94
+ def __post_init__(self):
95
+ if not self.propagated_at:
96
+ self.propagated_at = datetime.now(timezone.utc).isoformat()
97
+
98
+ def to_dict(self) -> Dict[str, Any]:
99
+ return {
100
+ "original_signal_type": self.original_signal_type,
101
+ "source_context": self.source_context,
102
+ "target_context": self.target_context,
103
+ "entity_name": self.entity_name,
104
+ "relationship": self.relationship,
105
+ "hop_count": self.hop_count,
106
+ "weight": round(self.weight, 3),
107
+ "details": self.details,
108
+ "propagated_at": self.propagated_at,
109
+ }
110
+
111
+
112
+ class SignalHierarchy:
113
+ """Manages context hierarchy and signal propagation.
114
+
115
+ Contexts are linked in a directed graph. Signals flow downstream
116
+ (from macro to micro) with decaying weight. Upstream queries flow
117
+ upward (from company to macro) for context building.
118
+ """
119
+
120
+ def __init__(self):
121
+ self._links: List[ContextLink] = []
122
+ self._downstream_map: Dict[str, List[ContextLink]] = {} # upstream -> [links]
123
+ self._upstream_map: Dict[str, List[ContextLink]] = {} # downstream -> [links]
124
+ self._lateral_map: Dict[str, List[ContextLink]] = {} # peer -> [links] (bidirectional)
125
+ self._context_levels: Dict[str, str] = {} # context -> level name
126
+ self._propagation_log: List[PropagatedSignal] = []
127
+
128
+ def add_link(self, link: ContextLink):
129
+ """Add a hierarchical link between two contexts (upstream → downstream)."""
130
+ self._links.append(link)
131
+ self._downstream_map.setdefault(link.upstream, []).append(link)
132
+ self._upstream_map.setdefault(link.downstream, []).append(link)
133
+ logger.info("[HIERARCHY] Link: %s -[%s]-> %s",
134
+ link.upstream, link.relationship, link.downstream)
135
+
136
+ def add_lateral_link(self, link: ContextLink):
137
+ """Add a lateral link between peer contexts (same level).
138
+
139
+ Lateral links represent: competitors, supply chain partners,
140
+ clients, sector peers — entities at the same hierarchy level
141
+ that influence each other sideways.
142
+ """
143
+ self._links.append(link)
144
+ self._lateral_map.setdefault(link.upstream, []).append(link)
145
+ self._lateral_map.setdefault(link.downstream, []).append(link)
146
+ logger.info("[HIERARCHY] Lateral: %s <-[%s]-> %s",
147
+ link.upstream, link.relationship, link.downstream)
148
+
149
+ def set_level(self, context_name: str, level: str):
150
+ """Set the hierarchy level for a context."""
151
+ self._context_levels[context_name] = level
152
+
153
+ def get_level(self, context_name: str) -> str:
154
+ """Get the hierarchy level for a context."""
155
+ return self._context_levels.get(context_name, "unknown")
156
+
157
+ def get_downstream(self, context_name: str, max_depth: int = 10) -> List[str]:
158
+ """Get all downstream contexts (recursive), ordered by proximity."""
159
+ result = []
160
+ visited: Set[str] = {context_name}
161
+ queue = [context_name]
162
+ depth = 0
163
+
164
+ while queue and depth < max_depth:
165
+ next_queue = []
166
+ for ctx in queue:
167
+ for link in self._downstream_map.get(ctx, []):
168
+ if link.downstream not in visited:
169
+ visited.add(link.downstream)
170
+ result.append(link.downstream)
171
+ next_queue.append(link.downstream)
172
+ queue = next_queue
173
+ depth += 1
174
+
175
+ return result
176
+
177
+ def get_upstream(self, context_name: str, max_depth: int = 10) -> List[str]:
178
+ """Get all upstream contexts (recursive), ordered by proximity."""
179
+ result = []
180
+ visited: Set[str] = {context_name}
181
+ queue = [context_name]
182
+ depth = 0
183
+
184
+ while queue and depth < max_depth:
185
+ next_queue = []
186
+ for ctx in queue:
187
+ for link in self._upstream_map.get(ctx, []):
188
+ if link.upstream not in visited:
189
+ visited.add(link.upstream)
190
+ result.append(link.upstream)
191
+ next_queue.append(link.upstream)
192
+ queue = next_queue
193
+ depth += 1
194
+
195
+ return result
196
+
197
+ def get_full_chain(self, context_name: str) -> Dict[str, List[str]]:
198
+ """Get both upstream and downstream chains for a context."""
199
+ return {
200
+ "upstream": self.get_upstream(context_name),
201
+ "downstream": self.get_downstream(context_name),
202
+ }
203
+
204
+ def propagate_signal(
205
+ self,
206
+ signal,
207
+ source_context: str,
208
+ max_depth: int = 5,
209
+ min_weight: float = 0.1,
210
+ direction: str = "both",
211
+ on_propagate: Optional[Callable] = None,
212
+ ) -> List[PropagatedSignal]:
213
+ """Propagate a signal through the hierarchy.
214
+
215
+ Signals can start at ANY level — a country event propagates both
216
+ down to companies AND up to world/geopolitical awareness.
217
+
218
+ Downstream (impact): full weight decay per hop.
219
+ Upstream (awareness): half weight — upstream contexts need to know,
220
+ but the impact is indirect.
221
+
222
+ Args:
223
+ signal: Signal dataclass from signals.py
224
+ source_context: Which context the signal originated in
225
+ max_depth: Maximum hops to propagate
226
+ min_weight: Stop propagating when weight falls below this
227
+ direction: "both" | "downstream" | "upstream"
228
+
229
+ Returns list of PropagatedSignal for each affected context.
230
+ """
231
+ propagated: List[PropagatedSignal] = []
232
+ visited: Set[str] = {source_context}
233
+
234
+ # Direction weight multipliers:
235
+ # downstream (impact): full weight — direct effect
236
+ # upstream (awareness): 0.5x — indirect, for awareness
237
+ # lateral (peer/supply chain): 0.7x — related but not hierarchical
238
+ dir_weights = {"downstream": 1.0, "upstream": 0.5, "lateral": 0.7}
239
+
240
+ # BFS: walk ALL connections from source — the signal is a wave
241
+ # Each queue item: (context, weight, hop_count)
242
+ queue = [(source_context, 1.0, 0)]
243
+
244
+ while queue:
245
+ current_ctx, current_weight, hop = queue.pop(0)
246
+ if hop >= max_depth:
247
+ continue
248
+
249
+ neighbors = []
250
+
251
+ # Downstream neighbors
252
+ if direction in ("both", "downstream", "all"):
253
+ for link in self._downstream_map.get(current_ctx, []):
254
+ neighbors.append((link.downstream, link, "downstream"))
255
+
256
+ # Upstream neighbors
257
+ if direction in ("both", "upstream", "all"):
258
+ for link in self._upstream_map.get(current_ctx, []):
259
+ neighbors.append((link.upstream, link, "upstream"))
260
+
261
+ # Lateral neighbors (same level — peers, supply chain, clients)
262
+ if direction in ("both", "lateral", "all"):
263
+ for link in self._lateral_map.get(current_ctx, []):
264
+ target = link.downstream if link.upstream == current_ctx else link.upstream
265
+ neighbors.append((target, link, "lateral"))
266
+
267
+ for target_ctx, link, flow_dir in neighbors:
268
+ if target_ctx in visited:
269
+ continue
270
+ if signal.type not in link.propagate_signals:
271
+ continue
272
+
273
+ dir_mult = dir_weights.get(flow_dir, 0.5)
274
+ next_weight = current_weight * link.weight * dir_mult
275
+
276
+ if next_weight < min_weight:
277
+ continue
278
+
279
+ visited.add(target_ctx)
280
+
281
+ prop = PropagatedSignal(
282
+ original_signal_type=signal.type,
283
+ source_context=source_context,
284
+ target_context=target_ctx,
285
+ entity_name=signal.entity_name,
286
+ relationship=link.relationship,
287
+ hop_count=hop + 1,
288
+ weight=next_weight,
289
+ details={
290
+ "direction": flow_dir,
291
+ "original_severity": signal.severity,
292
+ "signal_details": signal.details,
293
+ },
294
+ )
295
+ propagated.append(prop)
296
+ self._propagation_log.append(prop)
297
+ queue.append((target_ctx, next_weight, hop + 1))
298
+
299
+ if propagated:
300
+ by_dir = {}
301
+ for p in propagated:
302
+ d = p.details.get("direction", "unknown")
303
+ by_dir[d] = by_dir.get(d, 0) + 1
304
+ logger.info("[HIERARCHY] Signal '%s' from '%s': %s",
305
+ signal.type, source_context, by_dir)
306
+
307
+ return propagated
308
+
309
+ def get_propagation_log(self, limit: int = 50) -> List[Dict[str, Any]]:
310
+ """Get recent propagated signals."""
311
+ return [p.to_dict() for p in self._propagation_log[-limit:]]
312
+
313
+ def build_upstream_context(self, context_name: str) -> List[Dict[str, Any]]:
314
+ """Build a context briefing from all upstream contexts.
315
+
316
+ Returns a list of upstream signal summaries that downstream
317
+ agents/analysts should be aware of.
318
+ """
319
+ upstream = self.get_upstream(context_name)
320
+ briefing = []
321
+
322
+ for up_ctx in upstream:
323
+ level = self._context_levels.get(up_ctx, "unknown")
324
+ # Get recent propagated signals to this context
325
+ recent = [
326
+ p for p in self._propagation_log
327
+ if p.target_context == context_name and p.source_context == up_ctx
328
+ ]
329
+
330
+ briefing.append({
331
+ "context": up_ctx,
332
+ "level": level,
333
+ "relationship": self._get_relationship_to(up_ctx, context_name),
334
+ "recent_signals": [p.to_dict() for p in recent[-5:]],
335
+ })
336
+
337
+ return briefing
338
+
339
+ def _get_relationship_to(self, upstream: str, downstream: str) -> str:
340
+ """Get the relationship type between two contexts."""
341
+ for link in self._downstream_map.get(upstream, []):
342
+ if link.downstream == downstream:
343
+ return link.relationship
344
+ return "indirect"
345
+
346
+ def get_lateral(self, context_name: str) -> List[str]:
347
+ """Get all lateral (peer) contexts."""
348
+ peers = set()
349
+ for link in self._lateral_map.get(context_name, []):
350
+ peer = link.downstream if link.upstream == context_name else link.upstream
351
+ peers.add(peer)
352
+ return list(peers)
353
+
354
+ def get_all_connected(self, context_name: str) -> Dict[str, List[str]]:
355
+ """Get all connected contexts in every direction."""
356
+ return {
357
+ "upstream": self.get_upstream(context_name),
358
+ "downstream": self.get_downstream(context_name),
359
+ "lateral": self.get_lateral(context_name),
360
+ }
361
+
362
+ def to_dict(self) -> Dict[str, Any]:
363
+ """Serialize the hierarchy."""
364
+ hierarchical = [l for l in self._links if l.upstream in self._downstream_map
365
+ and any(dl.downstream == l.downstream for dl in self._downstream_map.get(l.upstream, []))]
366
+ lateral_links = []
367
+ seen = set()
368
+ for links in self._lateral_map.values():
369
+ for l in links:
370
+ key = tuple(sorted([l.upstream, l.downstream]))
371
+ if key not in seen:
372
+ seen.add(key)
373
+ lateral_links.append(l)
374
+
375
+ return {
376
+ "links": [l.to_dict() for l in self._links if l not in lateral_links],
377
+ "lateral_links": [l.to_dict() for l in lateral_links],
378
+ "levels": dict(self._context_levels),
379
+ }
380
+
381
+ @classmethod
382
+ def from_dict(cls, data: Dict[str, Any]) -> "SignalHierarchy":
383
+ """Deserialize a hierarchy."""
384
+ h = cls()
385
+ for link_data in data.get("links", []):
386
+ h.add_link(ContextLink.from_dict(link_data))
387
+ for link_data in data.get("lateral_links", []):
388
+ h.add_lateral_link(ContextLink.from_dict(link_data))
389
+ for ctx, level in data.get("levels", {}).items():
390
+ h.set_level(ctx, level)
391
+ return h
392
+
393
+
394
+ def build_default_hierarchy() -> SignalHierarchy:
395
+ """Build a sensible default hierarchy for financial analysis.
396
+
397
+ World → Geopolitical regions → Countries → Sectors → Companies
398
+ """
399
+ h = SignalHierarchy()
400
+
401
+ # Define levels
402
+ shared_contexts = {
403
+ "Global Macro": "world",
404
+ "Geopolitical Risk": "geopolitical",
405
+ "Commodities": "world",
406
+ "US Economy": "country",
407
+ "EU Economy": "country",
408
+ "China Economy": "country",
409
+ "India Economy": "country",
410
+ "Japan Economy": "country",
411
+ }
412
+ for ctx, level in shared_contexts.items():
413
+ h.set_level(ctx, level)
414
+
415
+ # World → Country links
416
+ for country in ["US Economy", "EU Economy", "China Economy", "India Economy", "Japan Economy"]:
417
+ h.add_link(ContextLink(
418
+ upstream="Global Macro",
419
+ downstream=country,
420
+ relationship="macro_affects",
421
+ weight=0.8,
422
+ ))
423
+ h.add_link(ContextLink(
424
+ upstream="Geopolitical Risk",
425
+ downstream=country,
426
+ relationship="risk_affects",
427
+ propagate_signals=["sentiment_reversal", "threshold_breach"],
428
+ weight=0.7,
429
+ ))
430
+ h.add_link(ContextLink(
431
+ upstream="Commodities",
432
+ downstream=country,
433
+ relationship="commodity_affects",
434
+ propagate_signals=["threshold_breach"],
435
+ weight=0.6,
436
+ ))
437
+
438
+ return h
@@ -0,0 +1,185 @@
1
+ """On-ingest signal processors for the correlation engine.
2
+
3
+ Lightweight checks that fire immediately when new tagged content arrives.
4
+ Each signal function checks a specific condition and returns a Signal
5
+ dataclass if triggered, or None if not.
6
+
7
+ Usage:
8
+ from contextsynapse.intelligence.signals import check_sentiment_reversal
9
+
10
+ signal = check_sentiment_reversal("Tesla", "negative", history, config)
11
+ if signal:
12
+ emit_event(signal)
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import logging
17
+ from dataclasses import dataclass, field
18
+ from datetime import datetime, timezone, timedelta
19
+ from typing import Any, Dict, List, Optional
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ @dataclass
25
+ class Signal:
26
+ """A fired signal from on-ingest processing."""
27
+ type: str # sentiment_reversal | threshold_breach | co_occurrence
28
+ entity_name: str # primary entity involved
29
+ severity: str = "info" # info | warning | alert
30
+ details: Dict[str, Any] = field(default_factory=dict)
31
+ fired_at: str = ""
32
+
33
+ def __post_init__(self):
34
+ if not self.fired_at:
35
+ self.fired_at = datetime.now(timezone.utc).isoformat()
36
+
37
+
38
+ def _parse_timestamp(ts: str) -> Optional[datetime]:
39
+ """Parse ISO timestamp string to datetime."""
40
+ try:
41
+ if ts.endswith("Z"):
42
+ ts = ts[:-1] + "+00:00"
43
+ return datetime.fromisoformat(ts)
44
+ except (ValueError, TypeError):
45
+ return None
46
+
47
+
48
+ def check_sentiment_reversal(
49
+ entity_name: str,
50
+ current_sentiment: str,
51
+ history: List[Dict[str, Any]],
52
+ config: Dict[str, Any],
53
+ ) -> Optional[Signal]:
54
+ """Check if entity sentiment has reversed from its recent trend.
55
+
56
+ Args:
57
+ entity_name: Name of the entity
58
+ current_sentiment: Current sentiment (positive/negative/neutral/mixed)
59
+ history: List of {"sentiment": str, "timestamp": str} dicts, most recent first
60
+ config: {"window_hours": int, "min_mentions": int}
61
+
62
+ Returns Signal if reversal detected, None otherwise.
63
+ """
64
+ window_hours = config.get("window_hours", 48)
65
+ min_mentions = config.get("min_mentions", 3)
66
+
67
+ if not history or len(history) < min_mentions:
68
+ return None
69
+
70
+ # Filter to window
71
+ cutoff = datetime.now(timezone.utc) - timedelta(hours=window_hours)
72
+ recent = []
73
+ for h in history:
74
+ ts = _parse_timestamp(h.get("timestamp", ""))
75
+ if ts and ts >= cutoff:
76
+ recent.append(h)
77
+
78
+ if len(recent) < min_mentions:
79
+ return None
80
+
81
+ # Determine dominant sentiment in history
82
+ sentiment_counts: Dict[str, int] = {}
83
+ for h in recent:
84
+ s = h.get("sentiment", "neutral")
85
+ sentiment_counts[s] = sentiment_counts.get(s, 0) + 1
86
+
87
+ if not sentiment_counts:
88
+ return None
89
+
90
+ dominant = max(sentiment_counts, key=sentiment_counts.__getitem__)
91
+
92
+ # Check for reversal — only fire when both sides are polar (positive/negative)
93
+ if current_sentiment != dominant and current_sentiment in ("positive", "negative"):
94
+ if dominant in ("positive", "negative"):
95
+ return Signal(
96
+ type="sentiment_reversal",
97
+ entity_name=entity_name,
98
+ severity="warning",
99
+ details={
100
+ "from": dominant,
101
+ "to": current_sentiment,
102
+ "history_count": len(recent),
103
+ "window_hours": window_hours,
104
+ },
105
+ )
106
+
107
+ return None
108
+
109
+
110
+ def check_threshold_breach(
111
+ entity_name: str,
112
+ history: List[Dict[str, Any]],
113
+ config: Dict[str, Any],
114
+ ) -> Optional[Signal]:
115
+ """Check if sentiment count exceeds threshold in window.
116
+
117
+ Args:
118
+ entity_name: Name of the entity
119
+ history: List of {"sentiment": str, "timestamp": str} dicts
120
+ config: {"metric": str, "threshold": int, "window_hours": int}
121
+
122
+ Returns Signal if threshold breached, None otherwise.
123
+ """
124
+ metric = config.get("metric", "negative_sentiment_count")
125
+ threshold = config.get("threshold", 5)
126
+ window_hours = config.get("window_hours", 24)
127
+
128
+ cutoff = datetime.now(timezone.utc) - timedelta(hours=window_hours)
129
+
130
+ # Derive target sentiment from metric name
131
+ target_sentiment = "negative" if "negative" in metric else "positive"
132
+ count = 0
133
+ for h in history:
134
+ ts = _parse_timestamp(h.get("timestamp", ""))
135
+ if ts and ts >= cutoff:
136
+ if h.get("sentiment") == target_sentiment:
137
+ count += 1
138
+
139
+ if count >= threshold:
140
+ return Signal(
141
+ type="threshold_breach",
142
+ entity_name=entity_name,
143
+ severity="alert",
144
+ details={
145
+ "metric": metric,
146
+ "count": count,
147
+ "threshold": threshold,
148
+ "window_hours": window_hours,
149
+ },
150
+ )
151
+
152
+ return None
153
+
154
+
155
+ def check_co_occurrence(
156
+ entity_a: str,
157
+ entity_b: str,
158
+ co_occurrence_count: int,
159
+ config: Dict[str, Any],
160
+ ) -> Optional[Signal]:
161
+ """Check if two entities are mentioned together frequently enough.
162
+
163
+ Args:
164
+ entity_a: First entity name
165
+ entity_b: Second entity name
166
+ co_occurrence_count: How many times they co-occurred in window
167
+ config: {"min_count": int, "window_days": int}
168
+
169
+ Returns Signal if co-occurrence threshold met, None otherwise.
170
+ """
171
+ min_count = config.get("min_count", 3)
172
+
173
+ if co_occurrence_count >= min_count:
174
+ return Signal(
175
+ type="co_occurrence",
176
+ entity_name=entity_a,
177
+ severity="info",
178
+ details={
179
+ "paired_with": entity_b,
180
+ "count": co_occurrence_count,
181
+ "min_count": min_count,
182
+ },
183
+ )
184
+
185
+ return None