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,918 @@
1
+ """
2
+ Ray Remote Functions for Pipeline Stages
3
+
4
+ Distributed execution of pipeline stages using Ray.
5
+ """
6
+
7
+ import logging
8
+ from typing import Dict, List, Any, Optional
9
+ import json
10
+ from pathlib import Path
11
+ import time
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ # Try to import Ray
16
+ try:
17
+ import ray
18
+ RAY_AVAILABLE = True
19
+ except ImportError:
20
+ RAY_AVAILABLE = False
21
+ logger.warning("Ray not available. Install with: pip install ray")
22
+
23
+
24
+ def _init_ray_if_needed() -> bool:
25
+ """
26
+ Initialize Ray if not already initialized with optimized configuration.
27
+
28
+ Uses configuration from ray.yaml if available, otherwise uses sensible defaults.
29
+ """
30
+ if not RAY_AVAILABLE:
31
+ return False
32
+
33
+ if not ray.is_initialized():
34
+ try:
35
+ # Try to load configuration
36
+ ray_config = None
37
+ try:
38
+ from ...ray.ray_config import RayConfigLoader
39
+ ray_config = RayConfigLoader.load_config()
40
+ except:
41
+ pass
42
+
43
+ # Configure Ray with optimal settings for chunking
44
+ init_kwargs = {
45
+ "ignore_reinit_error": True,
46
+ "num_cpus": None, # Use all available CPUs
47
+ "object_store_memory": 2 * 1024 * 1024 * 1024, # 2GB object store
48
+ "include_dashboard": False, # Disable dashboard for performance
49
+ "log_to_driver": False, # Reduce logging overhead
50
+ }
51
+
52
+ # Override with config if available
53
+ if ray_config:
54
+ if hasattr(ray_config, 'cluster') and ray_config.cluster:
55
+ if ray_config.cluster.get('address') and ray_config.cluster['address'] != 'auto':
56
+ init_kwargs['address'] = ray_config.cluster['address']
57
+
58
+ if hasattr(ray_config, 'resources') and ray_config.resources:
59
+ if ray_config.resources.get('object_store_memory_mb'):
60
+ init_kwargs['object_store_memory'] = ray_config.resources['object_store_memory_mb'] * 1024 * 1024
61
+
62
+ ray.init(**init_kwargs)
63
+ logger.info(f"Ray initialized for distributed pipeline execution (CPUs: {ray.cluster_resources().get('CPU', 'unknown')})")
64
+ return True
65
+ except Exception as e:
66
+ logger.error(f"Failed to initialize Ray: {e}")
67
+ return False
68
+
69
+ return True
70
+
71
+
72
+ if RAY_AVAILABLE:
73
+ @ray.remote(num_cpus=2, memory=2048 * 1024 * 1024) # 2 CPUs, 2GB memory
74
+ def remote_chunk_page(
75
+ page_data: Dict[str, Any],
76
+ document_id: str,
77
+ normalized_version: str,
78
+ chunking_strategy: str,
79
+ chunk_size: int,
80
+ overlap: int,
81
+ namespace: str,
82
+ base_dir: str,
83
+ chunking_params: Optional[Dict[str, Any]] = None,
84
+ normalized_doc_snapshot: Optional[Dict[str, Any]] = None
85
+ ) -> List[Dict[str, Any]]:
86
+ """
87
+ Remote function to chunk a single page with full strategy support.
88
+
89
+ Args:
90
+ page_data: Page data dictionary
91
+ document_id: Document identifier
92
+ normalized_version: Normalized document version
93
+ chunking_strategy: Chunking strategy name
94
+ chunk_size: Chunk size in characters
95
+ overlap: Overlap between chunks
96
+ namespace: Namespace name
97
+ base_dir: Base directory for storage
98
+ chunking_params: Additional chunking parameters (for advanced strategies)
99
+ normalized_doc_snapshot: Snapshot of normalized document (for strategies that need it)
100
+ """
101
+ try:
102
+ from ..engine.chunk_storage import ChunkStorage
103
+
104
+ chunk_storage = ChunkStorage(namespace=namespace, base_dir=base_dir)
105
+ page_no = page_data.get('page_no')
106
+ page_text = page_data.get('flat_text', '')
107
+ page = page_data # Full page data for strategies that need it
108
+
109
+ context = {
110
+ 'document_id': document_id,
111
+ 'page_no': page_no,
112
+ 'strategy': chunking_strategy,
113
+ 'namespace': namespace
114
+ }
115
+
116
+ logger.debug(f"[remote_chunk_page] Starting chunking for page {page_no} (text_length={len(page_text) if page_text else 0})")
117
+
118
+ if not page_text:
119
+ logger.warning(f"[remote_chunk_page] Page {page_no} has no text, returning empty chunks")
120
+ return []
121
+
122
+ chunking_params = chunking_params or {}
123
+
124
+ chunk_start_time = time.time()
125
+ try:
126
+ # Chunk the page text - support all strategies
127
+ if chunking_strategy == "semantic":
128
+ page_chunks = chunk_storage._chunk_semantic(page_text, chunk_size, overlap)
129
+ elif chunking_strategy == "paragraph":
130
+ page_chunks = chunk_storage._chunk_paragraph(page_text, overlap)
131
+ elif chunking_strategy == "recursive":
132
+ page_chunks = chunk_storage._chunk_recursive(page_text, chunk_size, overlap)
133
+ elif chunking_strategy == "sliding_window":
134
+ step_size = chunking_params.get('step_size', chunk_size - overlap)
135
+ page_chunks = chunk_storage._chunk_sliding_window(page_text, chunk_size, overlap, step_size=step_size)
136
+ elif chunking_strategy == "section_based":
137
+ section_markers = chunking_params.get('section_markers', ["##", "###", "Chapter", "Section", "Part", "#"])
138
+ preserve_hierarchy = chunking_params.get('preserve_hierarchy', True)
139
+ page_chunks = chunk_storage._chunk_section_based(page, chunk_size, overlap,
140
+ section_markers=section_markers,
141
+ preserve_hierarchy=preserve_hierarchy)
142
+ elif chunking_strategy == "table_aware":
143
+ # Need normalized doc for table positions
144
+ if normalized_doc_snapshot:
145
+ extract_tables = chunking_params.get('extract_tables', True)
146
+ preserve_table_context = chunking_params.get('preserve_table_context', True)
147
+ table_chunk_size = chunking_params.get('table_chunk_size', 300)
148
+ context_before = chunking_params.get('context_before', 200)
149
+ context_after = chunking_params.get('context_after', 200)
150
+ page_chunks = chunk_storage._chunk_table_aware(page, normalized_doc_snapshot, chunk_size, overlap,
151
+ extract_tables=extract_tables,
152
+ preserve_table_context=preserve_table_context,
153
+ table_chunk_size=table_chunk_size,
154
+ context_before=context_before,
155
+ context_after=context_after)
156
+ else:
157
+ # Fallback to semantic if no normalized doc
158
+ page_chunks = chunk_storage._chunk_semantic(page_text, chunk_size, overlap)
159
+ elif chunking_strategy == "smart":
160
+ # Need normalized doc for smart detection
161
+ if normalized_doc_snapshot:
162
+ document_type_detection = chunking_params.get('document_type_detection', True)
163
+ fallback_strategy = chunking_params.get('fallback_strategy', 'fixed')
164
+ page_chunks = chunk_storage._chunk_smart(page, normalized_doc_snapshot, chunk_size, overlap,
165
+ document_type_detection=document_type_detection,
166
+ fallback_strategy=fallback_strategy)
167
+ else:
168
+ # Fallback to semantic if no normalized doc
169
+ page_chunks = chunk_storage._chunk_semantic(page_text, chunk_size, overlap)
170
+ elif chunking_strategy == "token_based":
171
+ max_tokens = chunking_params.get('max_tokens', 512)
172
+ overlap_tokens = chunking_params.get('overlap_tokens', 50)
173
+ tokenizer = chunking_params.get('tokenizer', 'tiktoken')
174
+ model = chunking_params.get('model', 'gpt-3.5-turbo')
175
+ page_chunks = chunk_storage._chunk_token_based(page_text, max_tokens, overlap_tokens, tokenizer, model)
176
+ elif chunking_strategy == "semantic_similarity":
177
+ similarity_threshold = chunking_params.get('similarity_threshold', 0.7)
178
+ max_chunk_size = chunking_params.get('max_chunk_size', chunk_size)
179
+ min_chunk_size = chunking_params.get('min_chunk_size', 200)
180
+ embedding_model = chunking_params.get('embedding_model', 'sentence-transformers')
181
+ page_chunks = chunk_storage._chunk_semantic_similarity(page_text, similarity_threshold, max_chunk_size, min_chunk_size, embedding_model)
182
+ elif chunking_strategy == "topic_aware":
183
+ num_topics = chunking_params.get('num_topics', 10)
184
+ min_chunk_size = chunking_params.get('min_chunk_size', 300)
185
+ topic_model = chunking_params.get('topic_model', 'simple')
186
+ page_chunks = chunk_storage._chunk_topic_aware(page_text, num_topics, min_chunk_size, topic_model)
187
+ elif chunking_strategy == "qa_aware":
188
+ question_length = chunking_params.get('question_length', 50)
189
+ context_size = chunking_params.get('context_size', 500)
190
+ answer_markers = chunking_params.get('answer_markers', None)
191
+ page_chunks = chunk_storage._chunk_qa_aware(page_text, question_length, context_size, answer_markers)
192
+ elif chunking_strategy == "code_aware":
193
+ preserve_code_blocks = chunking_params.get('preserve_code_blocks', True)
194
+ code_context = chunking_params.get('code_context', 200)
195
+ min_code_block_size = chunking_params.get('min_code_block_size', 50)
196
+ page_chunks = chunk_storage._chunk_code_aware(page, chunk_size, overlap, preserve_code_blocks, code_context, min_code_block_size)
197
+ elif chunking_strategy == "image_aware":
198
+ if normalized_doc_snapshot:
199
+ include_captions = chunking_params.get('include_captions', True)
200
+ caption_context = chunking_params.get('caption_context', 300)
201
+ image_chunk_size = chunking_params.get('image_chunk_size', 200)
202
+ page_chunks = chunk_storage._chunk_image_aware(page, normalized_doc_snapshot, chunk_size, overlap, include_captions, caption_context, image_chunk_size)
203
+ else:
204
+ page_chunks = chunk_storage._chunk_semantic(page_text, chunk_size, overlap)
205
+ elif chunking_strategy == "adaptive":
206
+ base_chunk_size = chunking_params.get('base_chunk_size', chunk_size)
207
+ complexity_threshold = chunking_params.get('complexity_threshold', 0.5)
208
+ density_factor = chunking_params.get('density_factor', 1.2)
209
+ page_chunks = chunk_storage._chunk_adaptive(page_text, base_chunk_size, overlap, complexity_threshold, density_factor)
210
+ elif chunking_strategy == "entity_aware":
211
+ entity_types = chunking_params.get('entity_types', None)
212
+ page_chunks = chunk_storage._chunk_entity_aware(page_text, chunk_size, overlap, entity_types)
213
+ elif chunking_strategy == "multilang":
214
+ per_language_chunking = chunking_params.get('per_language_chunking', True)
215
+ page_chunks = chunk_storage._chunk_multilang(page_text, chunk_size, overlap, per_language_chunking)
216
+ elif chunking_strategy == "citation_aware":
217
+ citation_patterns = chunking_params.get('citation_patterns', None)
218
+ citation_context = chunking_params.get('citation_context', 300)
219
+ page_chunks = chunk_storage._chunk_citation_aware(page_text, chunk_size, overlap, citation_patterns, citation_context)
220
+ elif chunking_strategy == "dialogue_aware":
221
+ speaker_detection = chunking_params.get('speaker_detection', True)
222
+ preserve_turns = chunking_params.get('preserve_turns', True)
223
+ page_chunks = chunk_storage._chunk_dialogue_aware(page_text, chunk_size, overlap, speaker_detection, preserve_turns)
224
+ elif chunking_strategy == "formula_aware":
225
+ formula_patterns = chunking_params.get('formula_patterns', None)
226
+ formula_context = chunking_params.get('formula_context', 200)
227
+ page_chunks = chunk_storage._chunk_formula_aware(page_text, chunk_size, overlap, formula_patterns, formula_context)
228
+ elif chunking_strategy == "list_aware":
229
+ preserve_lists = chunking_params.get('preserve_lists', True)
230
+ list_context = chunking_params.get('list_context', 200)
231
+ page_chunks = chunk_storage._chunk_list_aware(page, chunk_size, overlap, preserve_lists, list_context)
232
+ else: # fixed (default)
233
+ page_chunks = chunk_storage._chunk_fixed(page_text, chunk_size, overlap)
234
+
235
+ chunk_time = time.time() - chunk_start_time
236
+ logger.debug(f"[remote_chunk_page] Page {page_no}: Created {len(page_chunks)} chunks in {chunk_time:.3f}s using {chunking_strategy}")
237
+ except Exception as chunk_err:
238
+ chunk_time = time.time() - chunk_start_time
239
+ logger.error(f"[remote_chunk_page] Error chunking page {page_no} with {chunking_strategy}: {chunk_err} (after {chunk_time:.3f}s)")
240
+ import traceback
241
+ logger.error(f"[remote_chunk_page] Traceback:\n{traceback.format_exc()}")
242
+ return []
243
+
244
+ # Create chunk properties
245
+ chunks = []
246
+ # Validate chunks don't exceed page boundaries
247
+ page_text_length = len(page_text)
248
+ validation_start = time.time()
249
+
250
+ chunks_validated = 0
251
+ chunks_skipped = 0
252
+ for chunk_idx, (chunk_text, start, end) in enumerate(page_chunks):
253
+ # Validate chunk boundaries are within page
254
+ if start < 0:
255
+ logger.warning(f"[remote_chunk_page] Page {page_no}, chunk {chunk_idx}: negative start ({start}), clamping to 0")
256
+ start = 0
257
+
258
+ if end > page_text_length:
259
+ logger.warning(f"[remote_chunk_page] Page {page_no}, chunk {chunk_idx}: exceeds boundary (end={end}, page_length={page_text_length}), clamping")
260
+ end = page_text_length
261
+ # Truncate chunk text to match
262
+ chunk_text = chunk_text[:end - start]
263
+
264
+ if start >= end:
265
+ logger.warning(f"[remote_chunk_page] Page {page_no}, chunk {chunk_idx}: invalid boundaries (start={start}, end={end}), skipping")
266
+ chunks_skipped += 1
267
+ continue
268
+
269
+ chunks_validated += 1
270
+
271
+ from contextsynapse.extraction.id_generator import IDGenerator
272
+ chunk_id = IDGenerator.generate_chunk_id(
273
+ document_id=document_id,
274
+ page_no=page_no,
275
+ chunk_index=chunk_idx,
276
+ chunking_strategy=chunking_strategy,
277
+ strategy_version="v1",
278
+ namespace=None
279
+ )
280
+ chunk_props = chunk_storage.create_chunk_with_pointer(
281
+ chunk_id=chunk_id,
282
+ content=chunk_text,
283
+ document_id=document_id,
284
+ normalized_version=normalized_version,
285
+ page_no=page_no,
286
+ start_char=start,
287
+ end_char=end,
288
+ chunk_index=chunk_idx,
289
+ chunking_strategy=chunking_strategy,
290
+ strategy_version="v1",
291
+ chunking_params={
292
+ "chunk_size": chunk_size,
293
+ "overlap": overlap,
294
+ **chunking_params
295
+ },
296
+ document_node_id=None, # Will be set later
297
+ metadata={
298
+ "page_boundary_validated": True, # Flag to indicate validation
299
+ }
300
+ )
301
+ chunks.append(chunk_props)
302
+
303
+ validation_time = time.time() - validation_start
304
+ total_time = time.time() - chunk_start_time
305
+ logger.info(f"[remote_chunk_page] Page {page_no} complete: {chunks_validated} chunks created, {chunks_skipped} skipped "
306
+ f"(validation: {validation_time:.3f}s, total: {total_time:.3f}s)")
307
+
308
+ return chunks
309
+ except Exception as e:
310
+ logger.error(f"[remote_chunk_page] Fatal error for page {page_no}: {e}")
311
+ import traceback
312
+ logger.error(f"[remote_chunk_page] Full traceback:\n{traceback.format_exc()}")
313
+ return []
314
+
315
+ @ray.remote(num_cpus=1, num_gpus=0.5, memory=4096 * 1024 * 1024) # 1 CPU, 0.5 GPU, 4GB memory
316
+ def remote_embed_chunk(
317
+ chunk_id: str,
318
+ content: str,
319
+ model: str,
320
+ dimensions: int,
321
+ embedding_field: str
322
+ ) -> Dict[str, Any]:
323
+ """Remote function to generate embedding for a single chunk."""
324
+ try:
325
+ from ...llm.openai_embedding_service import OpenAIEmbeddingService
326
+
327
+ embedding_service = OpenAIEmbeddingService()
328
+ embedding = embedding_service.generate_embedding(content)
329
+
330
+ return {
331
+ "chunk_id": chunk_id,
332
+ "embedding": embedding,
333
+ "embedding_field": embedding_field
334
+ }
335
+ except Exception as e:
336
+ logger.error(f"Error in remote_embed_chunk for {chunk_id}: {e}")
337
+ return {
338
+ "chunk_id": chunk_id,
339
+ "embedding": None,
340
+ "error": str(e)
341
+ }
342
+
343
+ @ray.remote(num_cpus=2, memory=2048 * 1024 * 1024) # 2 CPUs, 2GB memory
344
+ def remote_extract_entities_from_chunk(
345
+ chunk_id: str,
346
+ content: str,
347
+ llm_model: str,
348
+ prompt: str
349
+ ) -> Dict[str, Any]:
350
+ """Remote function to extract entities from a single chunk."""
351
+ try:
352
+ from ...llm.universal_llm import AIContextDBUniversalLLM
353
+
354
+ llm_manager = AIContextDBUniversalLLM()
355
+
356
+ # Prepare prompt
357
+ full_prompt = f"{prompt}\n\nText:\n{content[:2000]}" # Limit content size
358
+
359
+ # Call LLM
360
+ result = llm_manager.generate(
361
+ model_name=llm_model,
362
+ prompt=full_prompt,
363
+ temperature=0.3,
364
+ max_tokens=2000
365
+ )
366
+
367
+ if not result.get('success'):
368
+ return {
369
+ "chunk_id": chunk_id,
370
+ "entities": [],
371
+ "error": result.get('error', 'Unknown error')
372
+ }
373
+
374
+ response_text = result.get('response', '')
375
+
376
+ # Parse entities from response
377
+ try:
378
+ entities_data = json.loads(response_text)
379
+ if not isinstance(entities_data, list):
380
+ entities_data = [entities_data]
381
+ except:
382
+ # Fallback: try to extract entities from text response
383
+ import re
384
+ entities_data = []
385
+ patterns = [
386
+ r'(\w+):\s*([^(]+)\s*\(([^)]+)\)',
387
+ r'Name:\s*([^,]+),\s*Type:\s*([^,]+)',
388
+ ]
389
+ for pattern in patterns:
390
+ matches = re.findall(pattern, response_text)
391
+ for match in matches:
392
+ if len(match) >= 2:
393
+ entities_data.append({
394
+ 'name': match[1] if len(match) > 1 else match[0],
395
+ 'type': match[2] if len(match) > 2 else 'Entity'
396
+ })
397
+
398
+ return {
399
+ "chunk_id": chunk_id,
400
+ "entities": entities_data,
401
+ "error": None
402
+ }
403
+ except Exception as e:
404
+ logger.error(f"Error in remote_extract_entities_from_chunk for {chunk_id}: {e}")
405
+ return {
406
+ "chunk_id": chunk_id,
407
+ "entities": [],
408
+ "error": str(e)
409
+ }
410
+
411
+
412
+ def chunk_pages_parallel(
413
+ pages: List[Dict[str, Any]],
414
+ document_id: str,
415
+ normalized_version: str,
416
+ chunking_strategy: str,
417
+ chunk_size: int,
418
+ overlap: int,
419
+ namespace: str,
420
+ base_dir: str,
421
+ use_ray: bool = True,
422
+ chunking_params: Optional[Dict[str, Any]] = None,
423
+ normalized_doc: Optional[Dict[str, Any]] = None,
424
+ max_concurrent: Optional[int] = None
425
+ ) -> List[Dict[str, Any]]:
426
+ """
427
+ Chunk multiple pages in parallel using Ray with optimized batching.
428
+
429
+ Args:
430
+ pages: List of page data dictionaries
431
+ document_id: Document identifier
432
+ normalized_version: Normalized document version
433
+ chunking_strategy: Chunking strategy (all strategies supported)
434
+ chunk_size: Chunk size in characters
435
+ overlap: Overlap between chunks
436
+ namespace: Namespace name
437
+ base_dir: Base directory for storage
438
+ use_ray: Whether to use Ray for parallel processing
439
+ chunking_params: Additional chunking parameters for advanced strategies
440
+ normalized_doc: Full normalized document (for strategies that need it)
441
+ max_concurrent: Maximum concurrent Ray tasks (None = auto-detect)
442
+
443
+ Returns:
444
+ List of chunk property dictionaries
445
+ """
446
+ if not use_ray or not RAY_AVAILABLE or not _init_ray_if_needed():
447
+ # Fallback to sequential processing
448
+ from ..engine.chunk_storage import ChunkStorage
449
+ chunk_storage = ChunkStorage(namespace=namespace, base_dir=base_dir)
450
+
451
+ all_chunks = []
452
+ for page in pages:
453
+ page_no = page.get('page_no')
454
+ page_text = page.get('flat_text', '')
455
+
456
+ if not page_text:
457
+ continue
458
+
459
+ chunking_params = chunking_params or {}
460
+
461
+ # Support all strategies in fallback mode
462
+ if chunking_strategy == "semantic":
463
+ page_chunks = chunk_storage._chunk_semantic(page_text, chunk_size, overlap)
464
+ elif chunking_strategy == "paragraph":
465
+ page_chunks = chunk_storage._chunk_paragraph(page_text, overlap)
466
+ elif chunking_strategy == "recursive":
467
+ page_chunks = chunk_storage._chunk_recursive(page_text, chunk_size, overlap)
468
+ elif chunking_strategy == "sliding_window":
469
+ step_size = chunking_params.get('step_size', chunk_size - overlap)
470
+ page_chunks = chunk_storage._chunk_sliding_window(page_text, chunk_size, overlap, step_size=step_size)
471
+ elif chunking_strategy == "section_based":
472
+ section_markers = chunking_params.get('section_markers', ["##", "###", "Chapter", "Section", "Part", "#"])
473
+ preserve_hierarchy = chunking_params.get('preserve_hierarchy', True)
474
+ page_chunks = chunk_storage._chunk_section_based(page, chunk_size, overlap,
475
+ section_markers=section_markers,
476
+ preserve_hierarchy=preserve_hierarchy)
477
+ elif chunking_strategy == "table_aware" and normalized_doc:
478
+ extract_tables = chunking_params.get('extract_tables', True)
479
+ preserve_table_context = chunking_params.get('preserve_table_context', True)
480
+ table_chunk_size = chunking_params.get('table_chunk_size', 300)
481
+ context_before = chunking_params.get('context_before', 200)
482
+ context_after = chunking_params.get('context_after', 200)
483
+ page_chunks = chunk_storage._chunk_table_aware(page, normalized_doc, chunk_size, overlap,
484
+ extract_tables=extract_tables,
485
+ preserve_table_context=preserve_table_context,
486
+ table_chunk_size=table_chunk_size,
487
+ context_before=context_before,
488
+ context_after=context_after)
489
+ elif chunking_strategy == "smart" and normalized_doc:
490
+ document_type_detection = chunking_params.get('document_type_detection', True)
491
+ fallback_strategy = chunking_params.get('fallback_strategy', 'fixed')
492
+ page_chunks = chunk_storage._chunk_smart(page, normalized_doc, chunk_size, overlap,
493
+ document_type_detection=document_type_detection,
494
+ fallback_strategy=fallback_strategy)
495
+ elif chunking_strategy == "token_based":
496
+ max_tokens = chunking_params.get('max_tokens', 512)
497
+ overlap_tokens = chunking_params.get('overlap_tokens', 50)
498
+ tokenizer = chunking_params.get('tokenizer', 'tiktoken')
499
+ model = chunking_params.get('model', 'gpt-3.5-turbo')
500
+ page_chunks = chunk_storage._chunk_token_based(page_text, max_tokens, overlap_tokens, tokenizer, model)
501
+ elif chunking_strategy == "semantic_similarity":
502
+ similarity_threshold = chunking_params.get('similarity_threshold', 0.7)
503
+ max_chunk_size = chunking_params.get('max_chunk_size', chunk_size)
504
+ min_chunk_size = chunking_params.get('min_chunk_size', 200)
505
+ embedding_model = chunking_params.get('embedding_model', 'sentence-transformers')
506
+ page_chunks = chunk_storage._chunk_semantic_similarity(page_text, similarity_threshold, max_chunk_size, min_chunk_size, embedding_model)
507
+ elif chunking_strategy == "topic_aware":
508
+ num_topics = chunking_params.get('num_topics', 10)
509
+ min_chunk_size = chunking_params.get('min_chunk_size', 300)
510
+ topic_model = chunking_params.get('topic_model', 'simple')
511
+ page_chunks = chunk_storage._chunk_topic_aware(page_text, num_topics, min_chunk_size, topic_model)
512
+ elif chunking_strategy == "qa_aware":
513
+ question_length = chunking_params.get('question_length', 50)
514
+ context_size = chunking_params.get('context_size', 500)
515
+ answer_markers = chunking_params.get('answer_markers', None)
516
+ page_chunks = chunk_storage._chunk_qa_aware(page_text, question_length, context_size, answer_markers)
517
+ elif chunking_strategy == "code_aware" and normalized_doc:
518
+ preserve_code_blocks = chunking_params.get('preserve_code_blocks', True)
519
+ code_context = chunking_params.get('code_context', 200)
520
+ min_code_block_size = chunking_params.get('min_code_block_size', 50)
521
+ page_chunks = chunk_storage._chunk_code_aware(page, chunk_size, overlap, preserve_code_blocks, code_context, min_code_block_size)
522
+ elif chunking_strategy == "image_aware" and normalized_doc:
523
+ include_captions = chunking_params.get('include_captions', True)
524
+ caption_context = chunking_params.get('caption_context', 300)
525
+ image_chunk_size = chunking_params.get('image_chunk_size', 200)
526
+ page_chunks = chunk_storage._chunk_image_aware(page, normalized_doc, chunk_size, overlap, include_captions, caption_context, image_chunk_size)
527
+ elif chunking_strategy == "adaptive":
528
+ base_chunk_size = chunking_params.get('base_chunk_size', chunk_size)
529
+ complexity_threshold = chunking_params.get('complexity_threshold', 0.5)
530
+ density_factor = chunking_params.get('density_factor', 1.2)
531
+ page_chunks = chunk_storage._chunk_adaptive(page_text, base_chunk_size, overlap, complexity_threshold, density_factor)
532
+ elif chunking_strategy == "entity_aware":
533
+ entity_types = chunking_params.get('entity_types', None)
534
+ page_chunks = chunk_storage._chunk_entity_aware(page_text, chunk_size, overlap, entity_types)
535
+ elif chunking_strategy == "multilang":
536
+ per_language_chunking = chunking_params.get('per_language_chunking', True)
537
+ page_chunks = chunk_storage._chunk_multilang(page_text, chunk_size, overlap, per_language_chunking)
538
+ elif chunking_strategy == "citation_aware":
539
+ citation_patterns = chunking_params.get('citation_patterns', None)
540
+ citation_context = chunking_params.get('citation_context', 300)
541
+ page_chunks = chunk_storage._chunk_citation_aware(page_text, chunk_size, overlap, citation_patterns, citation_context)
542
+ elif chunking_strategy == "dialogue_aware":
543
+ speaker_detection = chunking_params.get('speaker_detection', True)
544
+ preserve_turns = chunking_params.get('preserve_turns', True)
545
+ page_chunks = chunk_storage._chunk_dialogue_aware(page_text, chunk_size, overlap, speaker_detection, preserve_turns)
546
+ elif chunking_strategy == "formula_aware":
547
+ formula_patterns = chunking_params.get('formula_patterns', None)
548
+ formula_context = chunking_params.get('formula_context', 200)
549
+ page_chunks = chunk_storage._chunk_formula_aware(page_text, chunk_size, overlap, formula_patterns, formula_context)
550
+ elif chunking_strategy == "list_aware" and normalized_doc:
551
+ preserve_lists = chunking_params.get('preserve_lists', True)
552
+ list_context = chunking_params.get('list_context', 200)
553
+ page_chunks = chunk_storage._chunk_list_aware(page, chunk_size, overlap, preserve_lists, list_context)
554
+ else:
555
+ page_chunks = chunk_storage._chunk_fixed(page_text, chunk_size, overlap)
556
+
557
+ for chunk_idx, (chunk_text, start, end) in enumerate(page_chunks):
558
+ from contextsynapse.extraction.id_generator import IDGenerator
559
+ chunk_id = IDGenerator.generate_chunk_id(
560
+ document_id=document_id,
561
+ page_no=page_no,
562
+ chunk_index=chunk_idx,
563
+ chunking_strategy=chunking_strategy,
564
+ strategy_version="v1",
565
+ namespace=None
566
+ )
567
+ chunk_props = chunk_storage.create_chunk_with_pointer(
568
+ chunk_id=chunk_id,
569
+ content=chunk_text,
570
+ document_id=document_id,
571
+ normalized_version=normalized_version,
572
+ page_no=page_no,
573
+ start_char=start,
574
+ end_char=end,
575
+ chunk_index=chunk_idx,
576
+ chunking_strategy=chunking_strategy,
577
+ strategy_version="v1",
578
+ chunking_params={"chunk_size": chunk_size, "overlap": overlap, **(chunking_params or {})},
579
+ document_node_id=None
580
+ )
581
+ all_chunks.append(chunk_props)
582
+
583
+ return all_chunks
584
+
585
+ # Use Ray for parallel processing with optimized batching
586
+ parallel_start = time.time()
587
+ logger.info(f"[chunk_pages_parallel] Starting parallel chunking: {len(pages)} pages, strategy={chunking_strategy}, "
588
+ f"chunk_size={chunk_size}, overlap={overlap}, namespace={namespace}")
589
+
590
+ # Validate pages are unique to prevent duplicate processing
591
+ page_numbers = [p.get('page_no') for p in pages if p.get('page_no') is not None]
592
+ unique_pages = len(set(page_numbers))
593
+ if unique_pages < len(page_numbers):
594
+ logger.warning(f"[chunk_pages_parallel] Duplicate page numbers detected! {len(page_numbers)} pages but only {unique_pages} unique. Deduplicating...")
595
+ # Deduplicate pages by page_no (keep first occurrence)
596
+ seen_pages = set()
597
+ deduplicated_pages = []
598
+ for page in pages:
599
+ page_no = page.get('page_no')
600
+ if page_no is not None and page_no not in seen_pages:
601
+ seen_pages.add(page_no)
602
+ deduplicated_pages.append(page)
603
+ elif page_no is None:
604
+ # Keep pages without page_no (shouldn't happen, but be safe)
605
+ deduplicated_pages.append(page)
606
+ pages = deduplicated_pages
607
+ logger.info(f"[chunk_pages_parallel] Deduplicated to {len(pages)} unique pages")
608
+
609
+ # Determine if we need normalized doc snapshot
610
+ needs_normalized_doc = chunking_strategy in ["table_aware", "smart", "image_aware", "code_aware", "list_aware"]
611
+ normalized_doc_snapshot = None
612
+ if needs_normalized_doc and normalized_doc:
613
+ # Create a lightweight snapshot (only what's needed)
614
+ # OPTIMIZATION: Only include tables/images metadata, not full page data
615
+ content = normalized_doc.get("content", {})
616
+ normalized_doc_snapshot = {
617
+ "document_id": normalized_doc.get("document_id"),
618
+ "content": {
619
+ "tables": content.get("tables", []),
620
+ "images": content.get("images", []) if chunking_strategy == "image_aware" else []
621
+ }
622
+ }
623
+ logger.debug(f"[chunk_pages_parallel] Created optimized normalized_doc snapshot: "
624
+ f"{len(normalized_doc_snapshot['content'].get('tables', []))} tables, "
625
+ f"{len(normalized_doc_snapshot['content'].get('images', []))} images")
626
+
627
+ # Optimize batch size based on strategy and available resources
628
+ if max_concurrent is None:
629
+ # Auto-detect based on available CPUs
630
+ try:
631
+ available_cpus = ray.cluster_resources().get("CPU", 4)
632
+ # Use 80% of available CPUs, but cap at reasonable limit
633
+ max_concurrent = min(int(available_cpus * 0.8), len(pages), 20)
634
+ except:
635
+ max_concurrent = min(len(pages), 10) # Conservative default
636
+
637
+ # OPTIMIZED: Process in batches with streaming results to prevent memory accumulation
638
+ # Use smaller batches and process results as they arrive
639
+ all_chunks = []
640
+ chunk_id_set = set() # Track chunk IDs to detect duplicates
641
+ duplicate_count = 0
642
+ batch_size = max_concurrent
643
+
644
+ import time
645
+ import gc
646
+ parallel_start_time = time.time()
647
+ total_batches = (len(pages) + batch_size - 1) // batch_size
648
+
649
+ print(f"[CHUNK] Ray parallel processing: {len(pages)} pages, {max_concurrent} concurrent workers, {total_batches} batches", flush=True)
650
+ print(f"[CHUNK] OPTIMIZED: Processing results incrementally to prevent memory buildup", flush=True)
651
+
652
+ for batch_start in range(0, len(pages), batch_size):
653
+ batch_end = min(batch_start + batch_size, len(pages))
654
+ batch_pages = pages[batch_start:batch_end]
655
+ batch_num = batch_start // batch_size + 1
656
+
657
+ batch_start_time = time.time()
658
+ logger.info(f"[chunk_pages_parallel] Batch {batch_num}/{total_batches}: Processing pages {batch_start+1}-{batch_end} of {len(pages)}")
659
+ print(f"[CHUNK] Ray batch {batch_num}/{total_batches}: Processing pages {batch_start+1}-{batch_end} of {len(pages)}", flush=True)
660
+
661
+ # Create futures for this batch
662
+ futures = [
663
+ remote_chunk_page.remote(
664
+ page, document_id, normalized_version, chunking_strategy,
665
+ chunk_size, overlap, namespace, base_dir,
666
+ chunking_params=chunking_params,
667
+ normalized_doc_snapshot=normalized_doc_snapshot
668
+ )
669
+ for page in batch_pages
670
+ ]
671
+
672
+ # OPTIMIZED: Process results as they complete using ray.wait() for streaming
673
+ # This allows processing chunks incrementally instead of waiting for entire batch
674
+ batch_results = []
675
+ remaining_futures = futures.copy()
676
+
677
+ while remaining_futures:
678
+ # Wait for at least one future to complete (timeout=1s to avoid blocking too long)
679
+ ready, remaining_futures = ray.wait(remaining_futures, num_returns=1, timeout=1.0)
680
+
681
+ for future in ready:
682
+ try:
683
+ page_chunks = ray.get(future)
684
+ batch_results.append(page_chunks)
685
+ except Exception as page_err:
686
+ logger.warning(f"[chunk_pages_parallel] Page chunking failed: {page_err}")
687
+ batch_results.append([]) # Continue with empty result
688
+
689
+ batch_time = time.time() - batch_start_time
690
+ batch_chunks = sum(len(page_chunks) for page_chunks in batch_results)
691
+ logger.info(f"[chunk_pages_parallel] Batch {batch_num} completed: {batch_chunks} chunks in {batch_time:.2f}s "
692
+ f"({batch_chunks/batch_time:.1f} chunks/sec)")
693
+
694
+ # OPTIMIZED: Process chunks from batch immediately and clear from memory
695
+ # This prevents accumulating all chunks in memory
696
+ batch_chunks_processed = 0
697
+ for page_chunks in batch_results:
698
+ for chunk in page_chunks:
699
+ chunk_id = chunk.get('chunk_id') or chunk.get('id')
700
+ if not chunk_id:
701
+ # Try to extract from source if available
702
+ source = chunk.get('source', {})
703
+ if isinstance(source, dict):
704
+ chunk_id = source.get('chunk_id')
705
+ if not chunk_id:
706
+ chunk_id = f"chunk_{len(all_chunks) + batch_chunks_processed}"
707
+
708
+ if chunk_id in chunk_id_set:
709
+ duplicate_count += 1
710
+ logger.warning(f"[chunk_pages_parallel] Duplicate chunk ID detected: {chunk_id}. Skipping duplicate.")
711
+ continue
712
+
713
+ chunk_id_set.add(chunk_id)
714
+ all_chunks.append(chunk)
715
+ batch_chunks_processed += 1
716
+
717
+ # Clear batch results from memory after processing
718
+ del batch_results
719
+ del futures
720
+ gc.collect() # Force garbage collection after each batch
721
+
722
+ elapsed = time.time() - parallel_start_time
723
+ remaining = len(pages) - batch_end
724
+ estimated_remaining = (remaining / len(batch_pages)) * batch_time if len(batch_pages) > 0 else 0
725
+ progress_pct = (batch_end / len(pages)) * 100
726
+
727
+ print(f"[CHUNK] Ray batch {batch_num} complete: {batch_chunks} chunks in {batch_time:.2f}s | Total: {len(all_chunks)} chunks | Progress: {progress_pct:.1f}% | Est. remaining: {estimated_remaining:.1f}s", flush=True)
728
+
729
+ logger.debug(f"[chunk_pages_parallel] Batch {batch_num} complete: {len(all_chunks)} unique chunks so far "
730
+ f"(skipped {duplicate_count} duplicates, progress: {progress_pct:.1f}%)")
731
+
732
+ total_time = time.time() - parallel_start_time
733
+ if duplicate_count > 0:
734
+ logger.warning(f"[chunk_pages_parallel] Detected and skipped {duplicate_count} duplicate chunks during parallel processing")
735
+
736
+ chunks_per_sec = len(all_chunks) / total_time if total_time > 0 else 0
737
+ print(f"[CHUNK] Ray parallel processing complete: {len(all_chunks)} unique chunks in {total_time:.2f}s ({chunks_per_sec:.1f} chunks/sec)", flush=True)
738
+ logger.info(f"[chunk_pages_parallel] Parallel processing complete: {len(all_chunks)} unique chunks in {total_time:.2f}s "
739
+ f"({chunks_per_sec:.1f} chunks/sec, {len(pages)/total_time:.1f} pages/sec)")
740
+
741
+ # Final cleanup
742
+ gc.collect()
743
+ return all_chunks
744
+
745
+
746
+ def embed_chunks_parallel(
747
+ chunks: List[Dict[str, Any]],
748
+ model: str = "text-embedding-3-large",
749
+ dimensions: int = 3072,
750
+ embedding_field: str = "embedding",
751
+ use_ray: bool = True
752
+ ) -> Dict[str, List[float]]:
753
+ """
754
+ Generate embeddings for multiple chunks in parallel using Ray.
755
+
756
+ Args:
757
+ chunks: List of chunk dictionaries with 'id' and 'content'
758
+ model: Embedding model name
759
+ dimensions: Embedding dimensions
760
+ embedding_field: Field name to store embedding
761
+ use_ray: Whether to use Ray for parallel processing
762
+
763
+ Returns:
764
+ Dictionary mapping chunk_id to embedding vector
765
+ """
766
+ if not chunks:
767
+ return {}
768
+
769
+ if not use_ray or not RAY_AVAILABLE or not _init_ray_if_needed():
770
+ # Fallback to sequential processing
771
+ try:
772
+ from ...llm.openai_embedding_service import OpenAIEmbeddingService
773
+ embedding_service = OpenAIEmbeddingService()
774
+ except ImportError:
775
+ logger.warning("OpenAI embedding service not available")
776
+ return {}
777
+
778
+ embeddings = {}
779
+ for chunk in chunks:
780
+ chunk_id = chunk.get("id", "")
781
+ content = chunk.get("content", "")
782
+ if content:
783
+ try:
784
+ embedding = embedding_service.generate_embedding(content)
785
+ embeddings[chunk_id] = embedding
786
+ except Exception as e:
787
+ logger.warning(f"Failed to embed chunk {chunk_id}: {e}")
788
+
789
+ return embeddings
790
+
791
+ # Use Ray for parallel processing
792
+ logger.info(f"Generating embeddings for {len(chunks)} chunks in parallel using Ray")
793
+ futures = [
794
+ remote_embed_chunk.remote(
795
+ chunk.get("id", ""),
796
+ chunk.get("content", ""),
797
+ model,
798
+ dimensions,
799
+ embedding_field
800
+ )
801
+ for chunk in chunks
802
+ ]
803
+
804
+ results = ray.get(futures)
805
+ embeddings = {}
806
+ for result in results:
807
+ if result.get("embedding"):
808
+ embeddings[result["chunk_id"]] = result["embedding"]
809
+
810
+ logger.info(f"Generated {len(embeddings)} embeddings in parallel")
811
+ return embeddings
812
+
813
+
814
+ def extract_entities_parallel(
815
+ chunks: List[Dict[str, Any]],
816
+ llm_model: str = "gpt-4",
817
+ prompt: str = "Extract all named entities from the text.",
818
+ use_ray: bool = True
819
+ ) -> Dict[str, List[Dict[str, Any]]]:
820
+ """
821
+ Extract entities from multiple chunks in parallel using Ray.
822
+
823
+ Args:
824
+ chunks: List of chunk dictionaries with 'id' and 'content'
825
+ llm_model: LLM model name
826
+ prompt: Prompt for entity extraction
827
+ use_ray: Whether to use Ray for parallel processing
828
+
829
+ Returns:
830
+ Dictionary mapping chunk_id to list of entities
831
+ """
832
+ if not chunks:
833
+ return {}
834
+
835
+ if not use_ray or not RAY_AVAILABLE or not _init_ray_if_needed():
836
+ # Fallback to sequential processing
837
+ try:
838
+ from ...llm.universal_llm import AIContextDBUniversalLLM
839
+ llm_manager = AIContextDBUniversalLLM()
840
+ except ImportError:
841
+ logger.warning("LLM module not available for entity extraction")
842
+ return {}
843
+
844
+ all_entities = {}
845
+ for chunk in chunks:
846
+ chunk_id = chunk.get("id", "")
847
+ content = chunk.get("content", "")
848
+ if not content:
849
+ continue
850
+
851
+ try:
852
+ full_prompt = f"{prompt}\n\nText:\n{content[:2000]}"
853
+ result = llm_manager.generate(
854
+ model_name=llm_model,
855
+ prompt=full_prompt,
856
+ temperature=0.3,
857
+ max_tokens=2000
858
+ )
859
+
860
+ if result.get('success'):
861
+ response_text = result.get('response', '')
862
+ try:
863
+ entities_data = json.loads(response_text)
864
+ if not isinstance(entities_data, list):
865
+ entities_data = [entities_data]
866
+ except:
867
+ entities_data = _parse_entities_from_text(response_text)
868
+ all_entities[chunk_id] = entities_data
869
+ except Exception as e:
870
+ logger.warning(f"Failed to extract entities from chunk {chunk_id}: {e}")
871
+
872
+ return all_entities
873
+
874
+ # Use Ray for parallel processing
875
+ logger.info(f"Extracting entities from {len(chunks)} chunks in parallel using Ray")
876
+ futures = [
877
+ remote_extract_entities_from_chunk.remote(
878
+ chunk.get("id", ""),
879
+ chunk.get("content", ""),
880
+ llm_model,
881
+ prompt
882
+ )
883
+ for chunk in chunks
884
+ ]
885
+
886
+ results = ray.get(futures)
887
+ all_entities = {}
888
+ for result in results:
889
+ if result.get("entities"):
890
+ all_entities[result["chunk_id"]] = result["entities"]
891
+
892
+ logger.info(f"Extracted entities from {len(all_entities)} chunks in parallel")
893
+ return all_entities
894
+
895
+
896
+ def _parse_entities_from_text_fallback(text: str) -> List[Dict[str, Any]]:
897
+ """Parse entities from text response (fallback method)."""
898
+ entities = []
899
+ import re
900
+ patterns = [
901
+ r'(\w+):\s*([^(]+)\s*\(([^)]+)\)',
902
+ r'Name:\s*([^,]+),\s*Type:\s*([^,]+)',
903
+ ]
904
+ for pattern in patterns:
905
+ matches = re.findall(pattern, text)
906
+ for match in matches:
907
+ if len(match) >= 2:
908
+ entities.append({
909
+ 'name': match[1] if len(match) > 1 else match[0],
910
+ 'type': match[2] if len(match) > 2 else 'Entity'
911
+ })
912
+ return entities
913
+
914
+
915
+ def _parse_entities_from_text(text: str) -> List[Dict[str, Any]]:
916
+ """Parse entities from text response (fallback method)."""
917
+ return _parse_entities_from_text_fallback(text)
918
+