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,82 @@
1
+ """LLM enrichment — deep code summaries for CodeModule nodes."""
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ from pathlib import Path
6
+ from typing import Any, Dict, List
7
+
8
+ from .helpers import _safe_read
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ _MAX_LLM_FILES = 15
13
+
14
+ _LLM_PROMPT = """\
15
+ Summarize this source code module in 2-3 sentences:
16
+ 1. What it does (purpose)
17
+ 2. Key dependencies it imports
18
+ 3. What could break (risks)
19
+
20
+ File: {path}
21
+
22
+ ```
23
+ {code}
24
+ ```
25
+
26
+ Reply with ONLY the summary, no markdown headings."""
27
+
28
+
29
+ def get_llm_client():
30
+ """Import and return the LLM client. Raises if unavailable."""
31
+ from contextsynapse.llm.client import get_llm_client as _get
32
+ return _get()
33
+
34
+
35
+ def scan_with_llm(repo_path: Path, code_nodes: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
36
+ """Enrich CodeModule nodes with LLM-generated summaries.
37
+
38
+ Returns the same nodes with richer ``summary`` properties.
39
+ If LLM is unavailable, returns nodes unchanged.
40
+ """
41
+ try:
42
+ client = get_llm_client()
43
+ except Exception:
44
+ logger.debug("scan_with_llm: no LLM available — returning nodes unchanged")
45
+ return code_nodes
46
+
47
+ enriched = []
48
+ llm_count = 0
49
+
50
+ for node in code_nodes:
51
+ if llm_count >= _MAX_LLM_FILES:
52
+ enriched.append(node)
53
+ continue
54
+
55
+ fpath = repo_path / node["properties"].get("path", "")
56
+ if not fpath.is_file():
57
+ enriched.append(node)
58
+ continue
59
+
60
+ code = _safe_read(fpath, limit=3000)
61
+ if not code or len(code) < 10:
62
+ enriched.append(node)
63
+ continue
64
+
65
+ try:
66
+ prompt = _LLM_PROMPT.format(path=node["properties"].get("path", ""), code=code)
67
+ summary = client.generate(prompt, system="You are a senior code reviewer. Be concise.", max_tokens=200)
68
+ llm_count += 1
69
+
70
+ if summary and len(summary.strip()) > 10:
71
+ new_node = dict(node)
72
+ new_node["properties"] = dict(node["properties"])
73
+ new_node["properties"]["summary"] = summary.strip()[:400]
74
+ enriched.append(new_node)
75
+ else:
76
+ enriched.append(node)
77
+ except Exception as exc:
78
+ logger.debug("scan_with_llm: failed for %s — %s", fpath, exc)
79
+ enriched.append(node)
80
+
81
+ logger.info("scan_with_llm: enriched %d / %d modules", llm_count, len(code_nodes))
82
+ return enriched
@@ -0,0 +1,149 @@
1
+ """Repo file scanners — README, source, tests, docs, API routes."""
2
+ from __future__ import annotations
3
+
4
+ import re
5
+ from pathlib import Path
6
+ from typing import Any, Dict, List
7
+
8
+ from .helpers import _safe_id, _safe_read, _find_src_dirs, _extract_summary, _SKIP_DIRS, _CODE_EXTENSIONS
9
+
10
+
11
+ def scan_readme(repo_path: Path) -> List[Dict[str, Any]]:
12
+ nodes = []
13
+ for name in ("README.md", "README.rst", "readme.md"):
14
+ readme = repo_path / name
15
+ if readme.exists():
16
+ text = readme.read_text(encoding="utf-8", errors="replace")
17
+ break
18
+ else:
19
+ return nodes
20
+
21
+ sections = re.split(r'\n#{1,3}\s+', text)
22
+ for section in sections[1:]:
23
+ lines = section.strip().split("\n")
24
+ title = lines[0].strip().rstrip("#").strip()
25
+ body = "\n".join(lines[1:]).strip()[:500]
26
+ if len(body) < 20:
27
+ continue
28
+ nodes.append({
29
+ "id": f"req:{_safe_id(title)}",
30
+ "label": "Requirement",
31
+ "properties": {"content": f"{title}: {body[:300]}", "source": "README.md", "version": 1},
32
+ })
33
+ return nodes
34
+
35
+
36
+ def scan_source_modules(repo_path: Path) -> List[Dict[str, Any]]:
37
+ nodes = []
38
+ for src_dir in _find_src_dirs(repo_path):
39
+ for fpath in sorted(src_dir.rglob("*")):
40
+ if not fpath.is_file() or fpath.suffix not in _CODE_EXTENSIONS:
41
+ continue
42
+ if any(p in fpath.parts for p in _SKIP_DIRS):
43
+ continue
44
+ if fpath.name.startswith("_") and fpath.name != "__init__.py":
45
+ continue
46
+ rel = fpath.relative_to(repo_path)
47
+ text = _safe_read(fpath, limit=2000)
48
+ if not text or len(text) < 50:
49
+ continue
50
+ summary = _extract_summary(text, fpath.suffix) or f"Module at {rel}"
51
+ nodes.append({
52
+ "id": f"code:{_safe_id(str(rel))}",
53
+ "label": "CodeModule",
54
+ "properties": {"summary": summary[:400], "path": str(rel), "version": 1},
55
+ })
56
+ return nodes
57
+
58
+
59
+ def scan_tests(repo_path: Path) -> List[Dict[str, Any]]:
60
+ nodes = []
61
+ test_dirs = []
62
+ for d in ("tests", "test", "spec", "specs", "__tests__"):
63
+ td = repo_path / d
64
+ if td.is_dir():
65
+ test_dirs.append(td)
66
+
67
+ seen = set()
68
+ for td in test_dirs:
69
+ for fpath in sorted(td.rglob("*")):
70
+ if not fpath.is_file() or fpath.suffix not in _CODE_EXTENSIONS:
71
+ continue
72
+ if fpath in seen:
73
+ continue
74
+ seen.add(fpath)
75
+ rel = fpath.relative_to(repo_path)
76
+ text = _safe_read(fpath, limit=1500)
77
+ if not text:
78
+ continue
79
+ test_funcs = re.findall(r'(?:def test_|it\(|test\(|func Test)', text)
80
+ if not test_funcs:
81
+ continue
82
+ summary = _extract_summary(text, fpath.suffix)
83
+ nodes.append({
84
+ "id": f"tc:{_safe_id(str(rel))}",
85
+ "label": "TestCase",
86
+ "properties": {
87
+ "what": summary[:200] if summary else f"Tests in {rel}",
88
+ "how": f"{len(test_funcs)} test function(s) in {rel}",
89
+ "version": 1,
90
+ },
91
+ })
92
+ return nodes
93
+
94
+
95
+ def scan_docs(repo_path: Path) -> List[Dict[str, Any]]:
96
+ nodes = []
97
+ for d in ("docs", "doc", "documentation", "adr", "adrs", "decisions"):
98
+ dd = repo_path / d
99
+ if not dd.is_dir():
100
+ continue
101
+ for fpath in sorted(dd.rglob("*.md")):
102
+ if any(p in fpath.parts for p in _SKIP_DIRS):
103
+ continue
104
+ rel = fpath.relative_to(repo_path)
105
+ text = _safe_read(fpath, limit=2000)
106
+ if not text or len(text) < 50:
107
+ continue
108
+ paragraphs = text.split("\n\n")
109
+ title = paragraphs[0].strip().lstrip("#").strip()
110
+ body = paragraphs[1].strip() if len(paragraphs) > 1 else ""
111
+ nodes.append({
112
+ "id": f"arch:{_safe_id(str(rel))}",
113
+ "label": "ArchDecision",
114
+ "properties": {"decision": title[:200], "rationale": body[:300], "source": str(rel), "version": 1},
115
+ })
116
+ return nodes
117
+
118
+
119
+ def scan_api_routes(repo_path: Path) -> List[Dict[str, Any]]:
120
+ nodes = []
121
+ patterns = [
122
+ r'@\w+\.(get|post|put|delete|patch)\(["\']([^"\']+)',
123
+ r'router\.(get|post|put|delete|patch)\(["\']([^"\']+)',
124
+ r'@(Get|Post|Put|Delete|Patch)Mapping\(["\']([^"\']+)',
125
+ ]
126
+ seen_ids = set()
127
+ for fpath in repo_path.rglob("*"):
128
+ if not fpath.is_file() or fpath.suffix not in (".py", ".ts", ".js", ".java"):
129
+ continue
130
+ if any(p in fpath.parts for p in _SKIP_DIRS):
131
+ continue
132
+ text = _safe_read(fpath, limit=5000)
133
+ if not text:
134
+ continue
135
+ rel = fpath.relative_to(repo_path)
136
+ for pattern in patterns:
137
+ for match in re.finditer(pattern, text):
138
+ method = match.group(1).upper()
139
+ path = match.group(2)
140
+ node_id = f"api:{_safe_id(f'{method}-{path}')}"
141
+ if node_id in seen_ids:
142
+ continue
143
+ seen_ids.add(node_id)
144
+ nodes.append({
145
+ "id": node_id,
146
+ "label": "APIContract",
147
+ "properties": {"method": method, "path": path, "source": str(rel), "version": 1},
148
+ })
149
+ return nodes
@@ -0,0 +1,213 @@
1
+ """SDLCScanOperator — orchestrates SDLC repo scanning via modular scanners.
2
+
3
+ Two modes:
4
+ Quick Scan (no clone) — GitHub API only, ~5 seconds
5
+ Full Scan (clone) — git clone + file scanning + API, ~30-120 seconds
6
+
7
+ Delegates to scanners/ package:
8
+ scanners.repo — README, source, tests, docs, API routes (Full only)
9
+ scanners.github — GitHub issues via .git/config (Full only)
10
+ scanners.github_api — GitHub API: README, issues, PRs, contributors, metadata (Quick)
11
+ scanners.git — git history, repo metadata (Full only)
12
+ scanners.edges — edge inference (7 types)
13
+ scanners.llm_enrichment — LLM-powered code summaries (Full only, optional)
14
+ scanners.jira — Jira ticket import (both modes)
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import logging
19
+ import os
20
+ from pathlib import Path
21
+ from typing import Any, Dict, List, TYPE_CHECKING
22
+
23
+ from .base import StageOperator
24
+
25
+ # Re-export everything from scanners for backward compatibility
26
+ from .scanners import (
27
+ scan_readme, scan_source_modules, scan_tests, scan_docs, scan_api_routes,
28
+ scan_github_issues_full, scan_git_history, scan_repo_metadata,
29
+ scan_with_llm, scan_jira_issues, infer_edges, quick_scan,
30
+ _safe_id, _issue_to_node, _extract_github_owner_repo,
31
+ )
32
+
33
+ if TYPE_CHECKING:
34
+ from ..ingest_content import Chunk
35
+ from ..stage_executor import GraphContext
36
+
37
+ logger = logging.getLogger(__name__)
38
+
39
+
40
+ class SDLCScanOperator(StageOperator):
41
+ """Scan a repository into typed SDLC graph nodes.
42
+
43
+ Modes:
44
+ quick (default): GitHub API only — no clone, ~5 seconds
45
+ full: git clone + file scan + API — ~30-120 seconds
46
+
47
+ Config (from pipeline_params):
48
+ scan_mode: "quick" or "full" (default: "quick")
49
+ skip_llm: skip LLM enrichment in full mode (default: True)
50
+ """
51
+
52
+ name = "sdlc_scan"
53
+
54
+ def __init__(self, config: Dict[str, Any] = None):
55
+ self.config = config or {}
56
+
57
+ def process(self, chunks: List["Chunk"], graph_ctx: "GraphContext") -> List["Chunk"]:
58
+ cfg = self.config
59
+ for chunk in chunks:
60
+ if chunk.metadata.get("pipeline_params"):
61
+ cfg = {**cfg, **chunk.metadata["pipeline_params"]}
62
+ break
63
+
64
+ # Get source URL or repo path
65
+ source_url = ""
66
+ repo_path_str = ""
67
+ for chunk in chunks:
68
+ source_url = chunk.metadata.get("source_url", "")
69
+ repo_path_str = chunk.metadata.get("repo_path", "")
70
+ if source_url or repo_path_str:
71
+ break
72
+
73
+ # Determine scan mode: auto-detect from input if not explicitly set
74
+ scan_mode = cfg.get("scan_mode", "")
75
+ if not scan_mode:
76
+ if repo_path_str and os.path.isdir(repo_path_str):
77
+ scan_mode = "full" # local directory → full scan
78
+ elif source_url and source_url.startswith("https://"):
79
+ scan_mode = "quick" # URL → quick scan (no clone by default)
80
+ else:
81
+ scan_mode = "full" # fallback
82
+
83
+ if scan_mode == "quick":
84
+ return self._quick_scan(source_url or repo_path_str, graph_ctx, cfg)
85
+ else:
86
+ return self._full_scan(repo_path_str, source_url, chunks, graph_ctx, cfg)
87
+
88
+ def _write_nodes_and_catch_orphans(
89
+ self, all_nodes: List[Dict], edges: List[Dict],
90
+ graph_ctx: "GraphContext", project_name: str,
91
+ ) -> None:
92
+ """Write nodes + edges, then connect orphans to a root Project node.
93
+
94
+ Most nodes connect to each other via inferred edges.
95
+ Only nodes with NO connections get linked to the root as a safety net.
96
+ """
97
+ # Write all nodes
98
+ for node_def in all_nodes:
99
+ graph_ctx.add_node(
100
+ label=node_def["label"],
101
+ properties=dict(node_def.get("properties", {})),
102
+ node_id=node_def["id"],
103
+ )
104
+
105
+ # Write all edges
106
+ for edge_def in edges:
107
+ graph_ctx.add_edge(
108
+ source_id=edge_def["source"],
109
+ target_id=edge_def["target"],
110
+ label=edge_def["label"],
111
+ )
112
+
113
+ # Find orphans — nodes with no edges at all
114
+ connected = set()
115
+ for e in edges:
116
+ connected.add(e["source"])
117
+ connected.add(e["target"])
118
+
119
+ orphans = [n for n in all_nodes if n["id"] not in connected]
120
+
121
+ if orphans:
122
+ # Create root node and link orphans to it
123
+ root_id = f"project:{_safe_id(project_name)}"
124
+ graph_ctx.add_node(
125
+ label="Project",
126
+ properties={"name": project_name, "version": 1},
127
+ node_id=root_id,
128
+ )
129
+ for orphan in orphans:
130
+ graph_ctx.add_edge(
131
+ source_id=root_id,
132
+ target_id=orphan["id"],
133
+ label="HAS_NODE",
134
+ )
135
+ logger.info("sdlc_scan: %d orphans connected to root node %s", len(orphans), root_id)
136
+
137
+ def _quick_scan(
138
+ self, url: str, graph_ctx: "GraphContext", cfg: Dict,
139
+ ) -> List["Chunk"]:
140
+ """Quick Scan — GitHub API only, no clone."""
141
+ if not url:
142
+ logger.warning("sdlc_scan[quick]: no URL provided — skipping")
143
+ return []
144
+
145
+ logger.info("sdlc_scan[quick]: scanning %s via API (no clone)", url)
146
+
147
+ all_nodes = quick_scan(url)
148
+ all_nodes += scan_jira_issues()
149
+
150
+ # Infer cross-connections
151
+ edges = infer_edges(all_nodes)
152
+
153
+ # Write nodes + edges, orphans fall back to root
154
+ from .scanners.github_api import _parse_owner_repo
155
+ project_name = _parse_owner_repo(url) or url.split("/")[-1] or "project"
156
+ self._write_nodes_and_catch_orphans(all_nodes, edges, graph_ctx, project_name)
157
+
158
+ logger.info("sdlc_scan[quick]: %d nodes, %d edges", len(all_nodes), len(edges))
159
+ return []
160
+
161
+ def _full_scan(
162
+ self, repo_path_str: str, source_url: str,
163
+ chunks: List["Chunk"], graph_ctx: "GraphContext", cfg: Dict,
164
+ ) -> List["Chunk"]:
165
+ """Full Scan — clone + file scanning + API."""
166
+ if not repo_path_str:
167
+ logger.warning("sdlc_scan[full]: no repo_path — skipping")
168
+ return chunks
169
+
170
+ repo_path = Path(repo_path_str)
171
+ if not repo_path.is_dir():
172
+ logger.warning("sdlc_scan[full]: %s is not a directory — skipping", repo_path)
173
+ return chunks
174
+
175
+ logger.info("sdlc_scan[full]: scanning %s (clone mode)", repo_path)
176
+
177
+ # File-based scanners
178
+ all_nodes = (
179
+ scan_readme(repo_path)
180
+ + scan_source_modules(repo_path)
181
+ + scan_tests(repo_path)
182
+ + scan_docs(repo_path)
183
+ + scan_api_routes(repo_path)
184
+ )
185
+
186
+ # LLM enrichment (optional)
187
+ skip_llm = cfg.get("skip_llm", False) or os.environ.get("SDLC_SKIP_LLM")
188
+ if not skip_llm:
189
+ code_nodes = [n for n in all_nodes if n["label"] == "CodeModule"]
190
+ non_code = [n for n in all_nodes if n["label"] != "CodeModule"]
191
+ all_nodes = non_code + scan_with_llm(repo_path, code_nodes)
192
+ else:
193
+ logger.info("sdlc_scan[full]: LLM enrichment skipped")
194
+
195
+ # API-based scanners
196
+ all_nodes += scan_github_issues_full(repo_path, source_url=source_url or repo_path_str)
197
+ all_nodes += scan_jira_issues()
198
+ all_nodes += scan_repo_metadata(repo_path)
199
+
200
+ # Git history
201
+ history_nodes, history_edges = scan_git_history(repo_path)
202
+ all_nodes += history_nodes
203
+
204
+ # Infer cross-connections + history edges
205
+ edges = infer_edges(all_nodes)
206
+ edges += history_edges
207
+
208
+ # Write nodes + edges, orphans fall back to root
209
+ project_name = repo_path.name or "project"
210
+ self._write_nodes_and_catch_orphans(all_nodes, edges, graph_ctx, project_name)
211
+
212
+ logger.info("sdlc_scan[full]: %d nodes, %d edges from %s", len(all_nodes), len(edges), repo_path)
213
+ return chunks
@@ -0,0 +1,149 @@
1
+ """SpecScanner — parse structured spec documents into SDLC nodes.
2
+
3
+ Parses markdown/text specs (from ChatGPT, Claude, PRDs, etc.) into typed
4
+ SDLC nodes by recognizing section headers:
5
+
6
+ ## Requirements / ## Functional Requirements → Requirement
7
+ ## Architecture / ## Design Decisions → ArchDecision
8
+ ## Constraints / ## Non-Functional → Constraint
9
+ ## Acceptance Criteria / ## Test Cases → TestCase
10
+ ## Goals / ## Objectives → Goal
11
+ ## User Stories → UserStory
12
+
13
+ Usage::
14
+
15
+ from contextsynapse.ingestion.universal.operators.spec_scanner import scan_spec_document
16
+ nodes = scan_spec_document(spec_text, source="chatgpt-spec.md")
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import logging
21
+ import re
22
+ from typing import Any, Dict, List, Tuple
23
+
24
+ logger = logging.getLogger(__name__)
25
+
26
+ # ── Section → Node Type mapping (loaded from schema) ─────────────────────────
27
+
28
+ from contextsynapse.project.sdlc_schema import SPEC_SECTION_MAP as _SECTION_MAP
29
+
30
+ _MAX_SPEC_NODES = 50
31
+
32
+
33
+ def _safe_id(text: str) -> str:
34
+ """Convert text to a safe node ID slug."""
35
+ s = re.sub(r'[^a-zA-Z0-9_-]', '-', text.lower())
36
+ s = re.sub(r'-+', '-', s).strip('-')
37
+ return s[:60]
38
+
39
+
40
+ def _classify_section(header: str) -> str:
41
+ """Map a section header to an SDLC node type. Returns '' if no match."""
42
+ header_lower = header.lower().strip()
43
+ for keywords, node_type in _SECTION_MAP:
44
+ for kw in keywords:
45
+ if kw in header_lower:
46
+ return node_type
47
+ return ""
48
+
49
+
50
+ def _extract_items(body: str) -> List[str]:
51
+ """Extract individual items from a section body.
52
+
53
+ Handles:
54
+ - Bullet lists (- item, * item, • item)
55
+ - Numbered lists (1. item, 1) item)
56
+ - Paragraphs separated by blank lines
57
+ """
58
+ # Try bullet/numbered list first
59
+ items = re.findall(r'(?:^|\n)\s*(?:[-*•]|\d+[.)]\s)\s*(.+)', body)
60
+ if items:
61
+ return [i.strip() for i in items if len(i.strip()) > 10]
62
+
63
+ # Fall back to paragraphs
64
+ paragraphs = [p.strip() for p in body.split("\n\n") if p.strip()]
65
+ return [p for p in paragraphs if len(p) > 10]
66
+
67
+
68
+ def _make_node(node_type: str, item_text: str, index: int, source: str) -> Dict[str, Any]:
69
+ """Create an SDLC node dict from a parsed spec item."""
70
+ node_id = f"spec:{_safe_id(item_text[:40])}-{index}"
71
+
72
+ if node_type == "Requirement":
73
+ props = {"content": item_text[:500], "source": source, "version": 1}
74
+ elif node_type == "ArchDecision":
75
+ props = {"decision": item_text[:500], "rationale": "", "source": source, "version": 1}
76
+ elif node_type == "Constraint":
77
+ props = {"description": item_text[:500], "source": source, "version": 1}
78
+ elif node_type == "TestCase":
79
+ props = {"what": item_text[:250], "how": "", "source": source, "version": 1}
80
+ elif node_type == "Goal":
81
+ props = {"content": item_text[:500], "source": source, "version": 1}
82
+ elif node_type == "UserStory":
83
+ props = {"content": item_text[:500], "source": source, "version": 1}
84
+ elif node_type == "DataModel":
85
+ props = {"summary": item_text[:500], "source": source, "version": 1}
86
+ elif node_type == "APIContract":
87
+ props = {"method": "", "path": "", "summary": item_text[:500], "source": source, "version": 1}
88
+ else:
89
+ props = {"content": item_text[:500], "source": source, "version": 1}
90
+
91
+ return {"id": node_id, "label": node_type, "properties": props}
92
+
93
+
94
+ def scan_spec_document(
95
+ text: str,
96
+ source: str = "spec",
97
+ ) -> List[Dict[str, Any]]:
98
+ """Parse a structured spec document into SDLC nodes.
99
+
100
+ Recognizes markdown headers (## Section Name) and maps them to SDLC
101
+ node types based on keywords. Items within each section become individual
102
+ nodes.
103
+
104
+ Args:
105
+ text: the spec document text (markdown or plain text)
106
+ source: source identifier for traceability
107
+
108
+ Returns:
109
+ List of SDLC node dicts: [{id, label, properties}, ...]
110
+ """
111
+ if not text or not text.strip():
112
+ return []
113
+
114
+ # Split by markdown headers (## or ###)
115
+ sections = re.split(r'\n#{2,3}\s+', text)
116
+ if len(sections) <= 1:
117
+ # No markdown headers — try plain text with "Section:" pattern
118
+ sections = re.split(r'\n(?=[A-Z][A-Za-z\s]+:)', text)
119
+
120
+ nodes: List[Dict[str, Any]] = []
121
+ node_index = 0
122
+
123
+ for section in sections:
124
+ lines = section.strip().split("\n")
125
+ if not lines:
126
+ continue
127
+
128
+ header = lines[0].strip().rstrip(":")
129
+ body = "\n".join(lines[1:]).strip()
130
+
131
+ node_type = _classify_section(header)
132
+ if not node_type:
133
+ continue
134
+
135
+ # Extract individual items from the section
136
+ items = _extract_items(body)
137
+ if not items:
138
+ # Treat the whole body as one item if no list structure
139
+ if body and len(body) > 10:
140
+ items = [body[:500]]
141
+
142
+ for item_text in items:
143
+ if node_index >= _MAX_SPEC_NODES:
144
+ break
145
+ nodes.append(_make_node(node_type, item_text, node_index, source))
146
+ node_index += 1
147
+
148
+ logger.info("scan_spec_document: %d nodes from '%s'", len(nodes), source)
149
+ return nodes
@@ -0,0 +1,72 @@
1
+ """StoreDocumentsOperator -- move heavy text to keep graph lean."""
2
+ from __future__ import annotations
3
+
4
+ import logging
5
+ import uuid
6
+ from typing import List, TYPE_CHECKING
7
+
8
+ from .base import StageOperator
9
+
10
+ if TYPE_CHECKING:
11
+ from ..ingest_content import Chunk
12
+ from ..stage_executor import GraphContext
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ _MAX_INLINE_LENGTH = 200
17
+ _CONTENT_FIELDS = ("content", "statement", "description")
18
+
19
+
20
+ class StoreDocumentsOperator(StageOperator):
21
+ name = "store_documents"
22
+
23
+ def process(self, chunks, graph_ctx):
24
+ # Try to get document store
25
+ doc_store = None
26
+ try:
27
+ from contextsynapse.storage.namespace_store import NamespaceStore
28
+ ns = NamespaceStore(graph_ctx.namespace or "default")
29
+ doc_store = ns
30
+ except Exception:
31
+ pass
32
+
33
+ count = 0
34
+ for node_id in list(graph_ctx.node_ids):
35
+ try:
36
+ node = graph_ctx.get_node(node_id)
37
+ if not node:
38
+ continue
39
+ props = getattr(node, "properties", {}) or {}
40
+ updates = {}
41
+ has_long = False
42
+
43
+ for field in _CONTENT_FIELDS:
44
+ val = props.get(field, "")
45
+ if isinstance(val, str) and len(val) > _MAX_INLINE_LENGTH:
46
+ has_long = True
47
+ if doc_store:
48
+ doc_id = f"doc_{uuid.uuid4().hex[:12]}"
49
+ try:
50
+ doc_store.store_document(doc_id, {
51
+ "node_id": node_id, "field": field,
52
+ "text": val, "label": getattr(node, "label", ""),
53
+ })
54
+ updates["_doc_ref"] = doc_id
55
+ except Exception:
56
+ pass
57
+ updates[field] = val[:_MAX_INLINE_LENGTH] + "..."
58
+
59
+ if has_long and updates:
60
+ try:
61
+ adapter = getattr(graph_ctx.db, "csr_adapter", graph_ctx.db)
62
+ if hasattr(adapter, "update_node_properties"):
63
+ adapter.update_node_properties(node_id, updates)
64
+ count += 1
65
+ except Exception:
66
+ pass
67
+ except Exception:
68
+ continue
69
+
70
+ if count:
71
+ logger.info("store_documents: truncated %d nodes", count)
72
+ return chunks