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,230 @@
1
+ """
2
+ Auto-Tagging & Classification
3
+ ===============================
4
+ Automatically classify graph nodes, contexts, and graphs with sensitivity levels
5
+ based on content analysis (PII detection, keyword matching, pattern recognition).
6
+
7
+ Tags: public | internal | confidential | restricted
8
+
9
+ Usage::
10
+
11
+ tagger = AutoTagger()
12
+ tags = tagger.classify_node(node_properties)
13
+ # {"sensitivity": "confidential", "tags": ["pii:email", "personal_data"], "pii_detected": True}
14
+
15
+ tagger.tag_context(context_id, graph_registry, context_manager)
16
+ # Scans all nodes, sets context-level sensitivity to highest found
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ import logging
22
+ import re
23
+ from dataclasses import dataclass, field
24
+ from typing import Any, Dict, List, Optional, Set
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ @dataclass
30
+ class ClassificationResult:
31
+ """Result of classifying a piece of content."""
32
+ sensitivity: str = "public" # public | internal | confidential | restricted
33
+ tags: List[str] = field(default_factory=list)
34
+ pii_detected: bool = False
35
+ confidence: float = 1.0
36
+ reason: str = ""
37
+
38
+ def to_dict(self) -> Dict[str, Any]:
39
+ return {
40
+ "sensitivity": self.sensitivity,
41
+ "tags": self.tags,
42
+ "pii_detected": self.pii_detected,
43
+ "confidence": self.confidence,
44
+ "reason": self.reason,
45
+ }
46
+
47
+
48
+ # Keyword patterns that indicate sensitivity levels
49
+ _CONFIDENTIAL_KEYWORDS = {
50
+ "salary", "compensation", "ssn", "social security", "bank account",
51
+ "credit card", "password", "secret key", "private key", "api key",
52
+ "medical", "diagnosis", "patient", "health record", "prescription",
53
+ "passport number", "aadhaar", "pan card",
54
+ }
55
+
56
+ _RESTRICTED_KEYWORDS = {
57
+ "classified", "top secret", "board meeting", "acquisition target",
58
+ "insider", "material nonpublic", "merger", "confidential strategy",
59
+ }
60
+
61
+ _INTERNAL_KEYWORDS = {
62
+ "internal only", "do not share", "draft", "work in progress",
63
+ "internal memo", "staff only", "employee",
64
+ }
65
+
66
+
67
+ class AutoTagger:
68
+ """Auto-classify content and tag with sensitivity levels."""
69
+
70
+ def __init__(self):
71
+ from .pii import get_pii_detector
72
+ self._pii = get_pii_detector()
73
+
74
+ def classify_text(self, text: str) -> ClassificationResult:
75
+ """Classify a text string by sensitivity level."""
76
+ if not text:
77
+ return ClassificationResult(sensitivity="public")
78
+
79
+ tags = []
80
+ reasons = []
81
+ text_lower = text.lower()
82
+
83
+ # 1. PII detection (highest priority)
84
+ pii_result = self._pii.scan(text)
85
+ pii_detected = pii_result.pii_found
86
+
87
+ if pii_detected:
88
+ for _, pii_type in pii_result.entities:
89
+ tags.append(f"pii:{pii_type}")
90
+ reasons.append(f"PII detected: {', '.join(set(t for _,t in pii_result.entities))}")
91
+
92
+ # 2. Keyword-based classification
93
+ sensitivity = pii_result.sensitivity if pii_detected else "public"
94
+
95
+ for kw in _RESTRICTED_KEYWORDS:
96
+ if kw in text_lower:
97
+ sensitivity = "restricted"
98
+ tags.append("classified")
99
+ reasons.append(f"Restricted keyword: {kw}")
100
+ break
101
+
102
+ if sensitivity not in ("restricted",):
103
+ for kw in _CONFIDENTIAL_KEYWORDS:
104
+ if kw in text_lower:
105
+ if sensitivity not in ("restricted",):
106
+ sensitivity = "confidential"
107
+ tags.append("sensitive_data")
108
+ reasons.append(f"Confidential keyword: {kw}")
109
+ break
110
+
111
+ if sensitivity == "public":
112
+ for kw in _INTERNAL_KEYWORDS:
113
+ if kw in text_lower:
114
+ sensitivity = "internal"
115
+ tags.append("internal")
116
+ reasons.append(f"Internal keyword: {kw}")
117
+ break
118
+
119
+ return ClassificationResult(
120
+ sensitivity=sensitivity,
121
+ tags=tags,
122
+ pii_detected=pii_detected,
123
+ confidence=0.9 if pii_detected else 0.7,
124
+ reason="; ".join(reasons) if reasons else "No sensitive content detected",
125
+ )
126
+
127
+ def classify_node(self, properties: Dict[str, Any]) -> ClassificationResult:
128
+ """Classify a graph node's properties."""
129
+ # Combine all text fields for analysis
130
+ text_fields = ["content", "description", "name", "title", "statement",
131
+ "body", "text", "summary", "rationale"]
132
+ combined = " ".join(
133
+ str(properties.get(f, "")) for f in text_fields if properties.get(f)
134
+ )
135
+ return self.classify_text(combined)
136
+
137
+ def tag_node(self, properties: Dict[str, Any]) -> Dict[str, Any]:
138
+ """Classify and add tags directly to node properties.
139
+
140
+ Returns updated properties dict with sensitivity, tags, pii_detected.
141
+ """
142
+ result = self.classify_node(properties)
143
+ tagged = dict(properties)
144
+ tagged["sensitivity"] = result.sensitivity
145
+ tagged["pii_detected"] = result.pii_detected
146
+
147
+ existing_tags = tagged.get("tags", [])
148
+ if isinstance(existing_tags, str):
149
+ existing_tags = [t.strip() for t in existing_tags.split(",") if t.strip()]
150
+ tagged["tags"] = list(set(existing_tags + result.tags))
151
+ tagged["_auto_classified"] = True
152
+
153
+ return tagged
154
+
155
+ def tag_context(self, context_id: str, graph_registry=None,
156
+ context_manager=None) -> Dict[str, Any]:
157
+ """Scan all nodes in a context and set context-level sensitivity.
158
+
159
+ The context gets the HIGHEST sensitivity found in any node.
160
+ """
161
+ if not context_manager or not graph_registry:
162
+ return {"error": "Missing context_manager or graph_registry"}
163
+
164
+ ctx = context_manager.get_context(context_id)
165
+ if not ctx:
166
+ return {"error": f"Context {context_id} not found"}
167
+
168
+ db = graph_registry.get_graph(ctx.graph_namespace, load_if_missing=True)
169
+ if not db:
170
+ return {"error": "Graph not available"}
171
+
172
+ # Scan all nodes
173
+ sensitivity_levels = {"public": 0, "internal": 1, "confidential": 2, "restricted": 3}
174
+ max_sensitivity = "public"
175
+ total_nodes = 0
176
+ pii_count = 0
177
+ tagged_count = 0
178
+
179
+ for node in db.get_all_nodes():
180
+ props = getattr(node, "properties", {}) or {}
181
+ total_nodes += 1
182
+
183
+ result = self.classify_node(props)
184
+
185
+ if result.pii_detected:
186
+ pii_count += 1
187
+
188
+ # Update node with classification
189
+ if not props.get("_auto_classified"):
190
+ tagged_props = self.tag_node(props)
191
+ try:
192
+ from ..core.graph_structures import GraphNode
193
+ db.add_node(GraphNode(
194
+ id=node.id, label=getattr(node, "label", ""),
195
+ properties=tagged_props,
196
+ ), write_through=True)
197
+ tagged_count += 1
198
+ except Exception:
199
+ pass
200
+
201
+ # Track highest sensitivity
202
+ if sensitivity_levels.get(result.sensitivity, 0) > sensitivity_levels.get(max_sensitivity, 0):
203
+ max_sensitivity = result.sensitivity
204
+
205
+ # Update context-level sensitivity
206
+ try:
207
+ context_manager.update_context(context_id, {"sensitivity": max_sensitivity})
208
+ except Exception:
209
+ pass
210
+
211
+ result = {
212
+ "context_id": context_id,
213
+ "total_nodes": total_nodes,
214
+ "nodes_tagged": tagged_count,
215
+ "pii_nodes": pii_count,
216
+ "context_sensitivity": max_sensitivity,
217
+ }
218
+ logger.info("[AUTO-TAG] Context %s: %d nodes scanned, %d PII, sensitivity=%s",
219
+ context_id[:12], total_nodes, pii_count, max_sensitivity)
220
+ return result
221
+
222
+
223
+ # Global singleton
224
+ _tagger: Optional[AutoTagger] = None
225
+
226
+ def get_auto_tagger() -> AutoTagger:
227
+ global _tagger
228
+ if _tagger is None:
229
+ _tagger = AutoTagger()
230
+ return _tagger
@@ -0,0 +1,218 @@
1
+ """
2
+ AIContextDB Data Security System
3
+ Comprehensive security including encryption, access control, PII detection, and audit logging.
4
+ """
5
+
6
+ import hashlib
7
+ import json
8
+ from typing import Dict, List, Any, Optional, Set, Tuple
9
+ from dataclasses import dataclass
10
+ from datetime import datetime
11
+ import logging
12
+ import re
13
+ from enum import Enum
14
+ from collections import defaultdict
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ class AccessLevel(Enum):
19
+ """Access levels for RBAC."""
20
+ READ = "read"
21
+ WRITE = "write"
22
+ DELETE = "delete"
23
+ ADMIN = "admin"
24
+
25
+ @dataclass
26
+ class AccessControl:
27
+ """Access control entry."""
28
+ user_id: str
29
+ resource: str
30
+ access_level: AccessLevel
31
+ granted_at: datetime
32
+ expires_at: Optional[datetime] = None
33
+
34
+ class PIIDetector:
35
+ """PII (Personally Identifiable Information) detector."""
36
+
37
+ # Patterns for common PII
38
+ EMAIL_PATTERN = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
39
+ PHONE_PATTERN = r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'
40
+ SSN_PATTERN = r'\b\d{3}-\d{2}-\d{4}\b'
41
+ CREDIT_CARD_PATTERN = r'\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b'
42
+
43
+ @staticmethod
44
+ def detect_pii(text: str) -> Dict[str, List[str]]:
45
+ """Detect PII in text."""
46
+ pii_found = {
47
+ 'emails': re.findall(PIIDetector.EMAIL_PATTERN, text),
48
+ 'phones': re.findall(PIIDetector.PHONE_PATTERN, text),
49
+ 'ssns': re.findall(PIIDetector.SSN_PATTERN, text),
50
+ 'credit_cards': re.findall(PIIDetector.CREDIT_CARD_PATTERN, text)
51
+ }
52
+
53
+ # Remove empty lists
54
+ return {k: v for k, v in pii_found.items() if v}
55
+
56
+ @staticmethod
57
+ def mask_pii(text: str, mask_char: str = '*') -> str:
58
+ """Mask PII in text."""
59
+ masked = text
60
+
61
+ # Mask emails
62
+ masked = re.sub(PIIDetector.EMAIL_PATTERN, lambda m: mask_char * len(m.group()), masked)
63
+
64
+ # Mask phones
65
+ masked = re.sub(PIIDetector.PHONE_PATTERN, lambda m: mask_char * len(m.group()), masked)
66
+
67
+ # Mask SSNs
68
+ masked = re.sub(PIIDetector.SSN_PATTERN, lambda m: mask_char * len(m.group()), masked)
69
+
70
+ # Mask credit cards
71
+ masked = re.sub(PIIDetector.CREDIT_CARD_PATTERN, lambda m: mask_char * len(m.group()), masked)
72
+
73
+ return masked
74
+
75
+ class DataSecurity:
76
+ """Comprehensive data security system."""
77
+
78
+ def __init__(self, namespace: str):
79
+ self.namespace = namespace
80
+ self.access_controls: Dict[str, List[AccessControl]] = defaultdict(list)
81
+ self.audit_log: List[Dict[str, Any]] = []
82
+ self.pii_detector = PIIDetector()
83
+ self.encryption_enabled = False
84
+
85
+ logger.info(f"[EMOJI] DataSecurity initialized for namespace: {namespace}")
86
+
87
+ def check_access(self, user_id: str, resource: str, required_level: AccessLevel) -> bool:
88
+ """Check if user has required access."""
89
+ if resource not in self.access_controls:
90
+ return False # No access by default
91
+
92
+ for acl in self.access_controls[resource]:
93
+ if acl.user_id == user_id:
94
+ # Check expiration
95
+ if acl.expires_at and datetime.now() > acl.expires_at:
96
+ continue
97
+
98
+ # Check access level
99
+ if self._has_sufficient_level(acl.access_level, required_level):
100
+ return True
101
+
102
+ return False
103
+
104
+ def _has_sufficient_level(self, granted: AccessLevel, required: AccessLevel) -> bool:
105
+ """Check if granted level is sufficient."""
106
+ level_hierarchy = {
107
+ AccessLevel.READ: 1,
108
+ AccessLevel.WRITE: 2,
109
+ AccessLevel.DELETE: 3,
110
+ AccessLevel.ADMIN: 4
111
+ }
112
+
113
+ return level_hierarchy.get(granted, 0) >= level_hierarchy.get(required, 0)
114
+
115
+ def grant_access(self, user_id: str, resource: str, access_level: AccessLevel,
116
+ expires_at: Optional[datetime] = None):
117
+ """Grant access to resource."""
118
+ acl = AccessControl(
119
+ user_id=user_id,
120
+ resource=resource,
121
+ access_level=access_level,
122
+ granted_at=datetime.now(),
123
+ expires_at=expires_at
124
+ )
125
+
126
+ self.access_controls[resource].append(acl)
127
+ self._audit_log('GRANT_ACCESS', user_id, resource, {'access_level': access_level.value})
128
+
129
+ def revoke_access(self, user_id: str, resource: str):
130
+ """Revoke access to resource."""
131
+ if resource in self.access_controls:
132
+ self.access_controls[resource] = [
133
+ acl for acl in self.access_controls[resource] if acl.user_id != user_id
134
+ ]
135
+ self._audit_log('REVOKE_ACCESS', user_id, resource)
136
+
137
+ def detect_and_mask_pii(self, data: Dict[str, Any]) -> Dict[str, Any]:
138
+ """Detect and mask PII in data."""
139
+ masked_data = data.copy()
140
+ pii_detected = {}
141
+
142
+ for key, value in data.items():
143
+ if isinstance(value, str):
144
+ detected = self.pii_detector.detect_pii(value)
145
+ if detected:
146
+ pii_detected[key] = detected
147
+ masked_data[key] = self.pii_detector.mask_pii(value)
148
+ elif isinstance(value, dict):
149
+ masked_data[key], nested_pii = self._detect_and_mask_nested(value)
150
+ if nested_pii:
151
+ pii_detected[key] = nested_pii
152
+
153
+ if pii_detected:
154
+ self._audit_log('PII_DETECTED', None, None, {'pii_types': list(pii_detected.keys())})
155
+
156
+ return masked_data, pii_detected
157
+
158
+ def _detect_and_mask_nested(self, data: Dict[str, Any]) -> Tuple[Dict[str, Any], Dict[str, Any]]:
159
+ """Recursively detect and mask PII in nested structures."""
160
+ masked = {}
161
+ pii_detected = {}
162
+
163
+ for key, value in data.items():
164
+ if isinstance(value, str):
165
+ detected = self.pii_detector.detect_pii(value)
166
+ if detected:
167
+ pii_detected[key] = detected
168
+ masked[key] = self.pii_detector.mask_pii(value)
169
+ else:
170
+ masked[key] = value
171
+ elif isinstance(value, dict):
172
+ nested_masked, nested_pii = self._detect_and_mask_nested(value)
173
+ masked[key] = nested_masked
174
+ if nested_pii:
175
+ pii_detected[key] = nested_pii
176
+ else:
177
+ masked[key] = value
178
+
179
+ return masked, pii_detected
180
+
181
+ def _audit_log(self, action: str, user_id: Optional[str], resource: Optional[str],
182
+ details: Dict[str, Any] = None):
183
+ """Log security event."""
184
+ log_entry = {
185
+ 'timestamp': datetime.now().isoformat(),
186
+ 'action': action,
187
+ 'user_id': user_id,
188
+ 'resource': resource,
189
+ 'details': details or {}
190
+ }
191
+
192
+ self.audit_log.append(log_entry)
193
+
194
+ # Keep only last 10000 entries
195
+ if len(self.audit_log) > 10000:
196
+ self.audit_log = self.audit_log[-10000:]
197
+
198
+ def get_audit_log(self, user_id: str = None, resource: str = None,
199
+ start_time: datetime = None, end_time: datetime = None) -> List[Dict[str, Any]]:
200
+ """Get audit log with filters."""
201
+ filtered = self.audit_log
202
+
203
+ if user_id:
204
+ filtered = [entry for entry in filtered if entry.get('user_id') == user_id]
205
+
206
+ if resource:
207
+ filtered = [entry for entry in filtered if entry.get('resource') == resource]
208
+
209
+ if start_time:
210
+ filtered = [entry for entry in filtered
211
+ if datetime.fromisoformat(entry['timestamp']) >= start_time]
212
+
213
+ if end_time:
214
+ filtered = [entry for entry in filtered
215
+ if datetime.fromisoformat(entry['timestamp']) <= end_time]
216
+
217
+ return filtered
218
+
@@ -0,0 +1,207 @@
1
+ """
2
+ Data Encryption Layer
3
+ ======================
4
+ Field-level encryption for graph node properties at rest.
5
+
6
+ Uses Fernet (AES-128-CBC) for symmetric encryption with key derivation
7
+ from a master secret. Supports searchable encryption via deterministic
8
+ hashing for keyword queries on encrypted fields.
9
+
10
+ For full homomorphic encryption on search, uses HMAC-based searchable
11
+ tokens that allow keyword matching without decrypting the full content.
12
+
13
+ Usage::
14
+
15
+ enc = FieldEncryptor(master_key="your-secret-key")
16
+
17
+ # Encrypt node properties before storage
18
+ encrypted = enc.encrypt_properties({"name": "John", "email": "john@x.com"}, fields=["email"])
19
+ # {"name": "John", "email": "gAAAAB...", "_encrypted_fields": ["email"]}
20
+
21
+ # Decrypt after retrieval
22
+ decrypted = enc.decrypt_properties(encrypted)
23
+ # {"name": "John", "email": "john@x.com"}
24
+
25
+ # Searchable token (allows keyword search on encrypted data)
26
+ token = enc.searchable_token("john@x.com")
27
+ # deterministic hash — same input always produces same token
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ import base64
33
+ import hashlib
34
+ import hmac
35
+ import json
36
+ import logging
37
+ import os
38
+ from typing import Any, Dict, List, Optional
39
+
40
+ logger = logging.getLogger(__name__)
41
+
42
+ # Try Fernet (cryptography package)
43
+ _FERNET_AVAILABLE = False
44
+ try:
45
+ from cryptography.fernet import Fernet
46
+ from cryptography.hazmat.primitives import hashes
47
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
48
+ _FERNET_AVAILABLE = True
49
+ except ImportError:
50
+ logger.info("cryptography package not installed — using fallback encryption")
51
+
52
+
53
+ class FieldEncryptor:
54
+ """Encrypt/decrypt individual node properties using Fernet (AES-128-CBC).
55
+
56
+ If the `cryptography` package isn't installed, falls back to
57
+ base64 encoding (NOT secure — for development only).
58
+ """
59
+
60
+ ENCRYPTED_PREFIX = "ENC:"
61
+ SEARCH_PREFIX = "STOK:"
62
+
63
+ def __init__(self, master_key: Optional[str] = None):
64
+ self._master_key = master_key or os.environ.get("CONTEXTSYNAPSE_ENCRYPTION_KEY") or os.environ.get("AICONTEXTDB_ENCRYPTION_KEY", "")
65
+ self._fernet = None
66
+ self._hmac_key = b""
67
+
68
+ if self._master_key and _FERNET_AVAILABLE:
69
+ # Derive Fernet key from master key using PBKDF2
70
+ salt = b"contextcore-field-encryption-v1"
71
+ kdf = PBKDF2HMAC(
72
+ algorithm=hashes.SHA256(),
73
+ length=32,
74
+ salt=salt,
75
+ iterations=100_000,
76
+ )
77
+ key = base64.urlsafe_b64encode(kdf.derive(self._master_key.encode()))
78
+ self._fernet = Fernet(key)
79
+ # Derive HMAC key for searchable tokens
80
+ self._hmac_key = hashlib.sha256(
81
+ (self._master_key + ":search-token").encode()
82
+ ).digest()
83
+ logger.info("[ENCRYPTION] Fernet encryption initialized")
84
+ elif self._master_key:
85
+ # Fallback HMAC key without Fernet
86
+ self._hmac_key = hashlib.sha256(
87
+ (self._master_key + ":search-token").encode()
88
+ ).digest()
89
+ logger.warning("[ENCRYPTION] Using base64 fallback (install cryptography for real encryption)")
90
+
91
+ @property
92
+ def available(self) -> bool:
93
+ return self._fernet is not None
94
+
95
+ def encrypt_value(self, value: str) -> str:
96
+ """Encrypt a single string value."""
97
+ if not value or not isinstance(value, str):
98
+ return value
99
+ if self._fernet:
100
+ token = self._fernet.encrypt(value.encode())
101
+ return self.ENCRYPTED_PREFIX + token.decode()
102
+ else:
103
+ # Fallback: base64 (NOT secure — development only)
104
+ encoded = base64.b64encode(value.encode()).decode()
105
+ return self.ENCRYPTED_PREFIX + "B64:" + encoded
106
+
107
+ def decrypt_value(self, value: str) -> str:
108
+ """Decrypt a single string value."""
109
+ if not isinstance(value, str) or not value.startswith(self.ENCRYPTED_PREFIX):
110
+ return value
111
+
112
+ payload = value[len(self.ENCRYPTED_PREFIX):]
113
+
114
+ if payload.startswith("B64:"):
115
+ # Base64 fallback
116
+ return base64.b64decode(payload[4:]).decode()
117
+
118
+ if self._fernet:
119
+ try:
120
+ return self._fernet.decrypt(payload.encode()).decode()
121
+ except Exception as e:
122
+ logger.warning("[ENCRYPTION] Decrypt failed: %s", e)
123
+ return "[DECRYPTION FAILED]"
124
+
125
+ return value
126
+
127
+ def encrypt_properties(self, properties: Dict[str, Any],
128
+ fields: Optional[List[str]] = None) -> Dict[str, Any]:
129
+ """Encrypt specified fields in a properties dict.
130
+
131
+ Args:
132
+ fields: Which fields to encrypt. Default: content, email, phone, ssn.
133
+ """
134
+ if not self._master_key:
135
+ return properties
136
+
137
+ target_fields = fields or ["content", "email", "phone", "ssn",
138
+ "credit_card", "aadhaar", "address"]
139
+ encrypted = dict(properties)
140
+ encrypted_fields = []
141
+
142
+ for field_name in target_fields:
143
+ if field_name in encrypted and isinstance(encrypted[field_name], str):
144
+ encrypted[field_name] = self.encrypt_value(encrypted[field_name])
145
+ encrypted_fields.append(field_name)
146
+
147
+ # Generate searchable token for encrypted field
148
+ token = self.searchable_token(str(properties[field_name]))
149
+ encrypted[f"_stok_{field_name}"] = token
150
+
151
+ if encrypted_fields:
152
+ encrypted["_encrypted_fields"] = encrypted_fields
153
+
154
+ return encrypted
155
+
156
+ def decrypt_properties(self, properties: Dict[str, Any]) -> Dict[str, Any]:
157
+ """Decrypt all encrypted fields in a properties dict."""
158
+ encrypted_fields = properties.get("_encrypted_fields", [])
159
+ if not encrypted_fields:
160
+ return properties
161
+
162
+ decrypted = dict(properties)
163
+ for field_name in encrypted_fields:
164
+ if field_name in decrypted:
165
+ decrypted[field_name] = self.decrypt_value(decrypted[field_name])
166
+
167
+ # Remove encryption metadata from output
168
+ decrypted.pop("_encrypted_fields", None)
169
+ for f in encrypted_fields:
170
+ decrypted.pop(f"_stok_{f}", None)
171
+
172
+ return decrypted
173
+
174
+ def searchable_token(self, value: str) -> str:
175
+ """Generate a deterministic searchable token for encrypted content.
176
+
177
+ This enables keyword search on encrypted fields without decryption:
178
+ - Same plaintext always produces the same token
179
+ - Token cannot be reversed to get the plaintext
180
+ - Allows exact-match search on encrypted fields
181
+
182
+ For substring search, tokens are generated for each word.
183
+ """
184
+ if not self._hmac_key:
185
+ return ""
186
+ h = hmac.new(self._hmac_key, value.lower().strip().encode(), hashlib.sha256)
187
+ return self.SEARCH_PREFIX + h.hexdigest()[:16]
188
+
189
+ def searchable_tokens_for_text(self, text: str) -> List[str]:
190
+ """Generate searchable tokens for each significant word in text.
191
+
192
+ Enables keyword search on encrypted content.
193
+ """
194
+ if not self._hmac_key:
195
+ return []
196
+ words = set(w.lower() for w in text.split() if len(w) > 3)
197
+ return [self.searchable_token(w) for w in words]
198
+
199
+
200
+ # Global singleton
201
+ _encryptor: Optional[FieldEncryptor] = None
202
+
203
+ def get_encryptor() -> FieldEncryptor:
204
+ global _encryptor
205
+ if _encryptor is None:
206
+ _encryptor = FieldEncryptor()
207
+ return _encryptor