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,401 @@
1
+ """TenantIsolation — ensures data separation between AMCs/organizations.
2
+
3
+ Every resource belongs to a tenant. Users can only access resources
4
+ within their tenant. Cross-tenant access is never allowed (even for admins).
5
+
6
+ In dev mode: a single default tenant is used.
7
+ In production: tenant is extracted from JWT and enforced on every query.
8
+
9
+ Namespace isolation (legacy):
10
+ ti = TenantIsolation()
11
+ ns = ti.namespace("alpha_capital", "portfolio_growth")
12
+ # -> "alpha_capital_portfolio_growth"
13
+
14
+ ti.validate_access("alpha_capital", ns) # True
15
+ ti.validate_access("beta_wealth", ns) # False
16
+ ti.validate_access("anyone", "market_nifty50") # True (shared)
17
+
18
+ Tenant management (new — PostgreSQL-backed):
19
+ tm = TenantManager()
20
+ tenant = tm.create_tenant("Alpha Capital", "alpha-capital", plan="pro")
21
+ tm.get_tenant(tenant["id"])
22
+ tm.suspend_tenant(tenant["id"], reason="Non-payment")
23
+ """
24
+ from __future__ import annotations
25
+
26
+ import logging
27
+ import os
28
+ import re
29
+ import uuid
30
+ from datetime import datetime, timezone
31
+ from typing import Any, Dict, List, Optional, Set
32
+
33
+ from fastapi import HTTPException, Request
34
+
35
+ logger = logging.getLogger(__name__)
36
+
37
+
38
+ # ── Shared namespace prefixes (platform-level data) ──────────────────────────
39
+ # Namespace prefixes that are shared across all tenants
40
+ SHARED_PREFIXES: List[str] = [
41
+ "market_",
42
+ "stock_",
43
+ "macro_",
44
+ "regulatory_",
45
+ "fund_nav_",
46
+ "sector_",
47
+ "index_",
48
+ "currency_",
49
+ "fii_",
50
+ ]
51
+
52
+ # Known tenant IDs (populated at runtime)
53
+ _known_tenants: Set[str] = set()
54
+
55
+ # Default tenant for dev mode
56
+ DEFAULT_TENANT_SLUG = "dev"
57
+ DEFAULT_TENANT_NAME = "Development"
58
+
59
+
60
+ # ── Namespace isolation (legacy, kept for backward compat) ───────────────────
61
+
62
+ class TenantIsolation:
63
+ """Enforces tenant-scoped namespace isolation."""
64
+
65
+ def __init__(self):
66
+ self._known_tenants: Set[str] = set()
67
+
68
+ def namespace(self, tenant_id: str, resource: str) -> str:
69
+ """Create a tenant-scoped namespace."""
70
+ safe_tenant = re.sub(r'[^a-zA-Z0-9_]', '_', tenant_id)
71
+ safe_resource = re.sub(r'[^a-zA-Z0-9_]', '_', resource)
72
+ self._known_tenants.add(safe_tenant)
73
+ return f"{safe_tenant}_{safe_resource}"
74
+
75
+ def is_shared(self, namespace: str) -> bool:
76
+ """Check if a namespace is shared (platform-level market data)."""
77
+ return any(namespace.startswith(prefix) for prefix in SHARED_PREFIXES)
78
+
79
+ def extract_tenant(self, namespace: str) -> Optional[str]:
80
+ """Extract tenant ID from a namespaced string."""
81
+ if self.is_shared(namespace):
82
+ return None
83
+
84
+ # Try to match against known tenants
85
+ for tenant in self._known_tenants:
86
+ if namespace.startswith(f"{tenant}_"):
87
+ return tenant
88
+
89
+ return None
90
+
91
+ def validate_access(
92
+ self, tenant_id: str, namespace: str
93
+ ) -> bool:
94
+ """Check if a tenant can access a namespace."""
95
+ # Shared namespaces accessible to all
96
+ if self.is_shared(namespace):
97
+ return True
98
+
99
+ # Tenant can access their own namespaces
100
+ safe_tenant = re.sub(r'[^a-zA-Z0-9_]', '_', tenant_id)
101
+ return namespace.startswith(f"{safe_tenant}_")
102
+
103
+
104
+ # ── Tenant Manager (PostgreSQL-backed) ───────────────────────────────────────
105
+
106
+ class TenantManager:
107
+ """Manages tenants in the database (PostgreSQL or SQLite).
108
+
109
+ Uses contextsynapse.core.db for database access, so it works with both
110
+ backends seamlessly.
111
+ """
112
+
113
+ _DDL_PG = """
114
+ CREATE TABLE IF NOT EXISTS tenants (
115
+ id TEXT PRIMARY KEY,
116
+ name TEXT NOT NULL,
117
+ slug TEXT NOT NULL UNIQUE,
118
+ plan TEXT NOT NULL DEFAULT 'free',
119
+ settings TEXT NOT NULL DEFAULT '{}',
120
+ is_active BOOLEAN NOT NULL DEFAULT TRUE,
121
+ suspended BOOLEAN NOT NULL DEFAULT FALSE,
122
+ suspend_reason TEXT,
123
+ created_at TIMESTAMP NOT NULL DEFAULT NOW(),
124
+ updated_at TIMESTAMP NOT NULL DEFAULT NOW()
125
+ );
126
+ CREATE INDEX IF NOT EXISTS idx_tenants_slug ON tenants(slug);
127
+ CREATE INDEX IF NOT EXISTS idx_tenants_active ON tenants(is_active);
128
+ """
129
+
130
+ _DDL_SQLITE = """
131
+ CREATE TABLE IF NOT EXISTS tenants (
132
+ id TEXT PRIMARY KEY,
133
+ name TEXT NOT NULL,
134
+ slug TEXT NOT NULL UNIQUE,
135
+ plan TEXT NOT NULL DEFAULT 'free',
136
+ settings TEXT NOT NULL DEFAULT '{}',
137
+ is_active INTEGER NOT NULL DEFAULT 1,
138
+ suspended INTEGER NOT NULL DEFAULT 0,
139
+ suspend_reason TEXT,
140
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
141
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
142
+ );
143
+ CREATE INDEX IF NOT EXISTS idx_tenants_slug ON tenants(slug);
144
+ CREATE INDEX IF NOT EXISTS idx_tenants_active ON tenants(is_active);
145
+ """
146
+
147
+ def __init__(self):
148
+ from ..core.db import IS_POSTGRES
149
+ self._is_pg = IS_POSTGRES
150
+ self._ensure_table()
151
+
152
+ def _ensure_table(self):
153
+ """Create tenants table if it doesn't exist."""
154
+ from ..core.db import transaction, run_ddl, IS_POSTGRES
155
+ try:
156
+ with transaction() as (conn, _cur):
157
+ ddl = self._DDL_PG if IS_POSTGRES else self._DDL_SQLITE
158
+ run_ddl(conn, ddl)
159
+ except Exception as exc:
160
+ logger.warning("Could not create tenants table: %s", exc)
161
+
162
+ # ── CRUD ─────────────────────────────────────────────────────────────────
163
+
164
+ def create_tenant(
165
+ self,
166
+ name: str,
167
+ slug: str,
168
+ plan: str = "free",
169
+ settings: Optional[Dict[str, Any]] = None,
170
+ ) -> Dict[str, Any]:
171
+ """Create a new tenant. Returns the tenant dict."""
172
+ import json
173
+ from ..core.db import transaction, PH, integrity_error
174
+
175
+ tenant_id = str(uuid.uuid4())
176
+ now = datetime.now(timezone.utc).isoformat()
177
+ settings_json = json.dumps(settings or {})
178
+
179
+ try:
180
+ with transaction() as (conn, cur):
181
+ cur.execute(
182
+ f"INSERT INTO tenants (id, name, slug, plan, settings, created_at, updated_at) "
183
+ f"VALUES ({PH}, {PH}, {PH}, {PH}, {PH}, {PH}, {PH})",
184
+ (tenant_id, name, slug, plan, settings_json, now, now),
185
+ )
186
+ except integrity_error():
187
+ raise ValueError(f"Tenant with slug '{slug}' already exists")
188
+
189
+ return {
190
+ "id": tenant_id,
191
+ "name": name,
192
+ "slug": slug,
193
+ "plan": plan,
194
+ "settings": settings or {},
195
+ "is_active": True,
196
+ "suspended": False,
197
+ "suspend_reason": None,
198
+ "created_at": now,
199
+ "updated_at": now,
200
+ }
201
+
202
+ def get_tenant(self, tenant_id: str) -> Optional[Dict[str, Any]]:
203
+ """Get a tenant by ID."""
204
+ from ..core.db import transaction, PH, row_to_dict
205
+ with transaction() as (_conn, cur):
206
+ cur.execute(
207
+ f"SELECT * FROM tenants WHERE id = {PH}", (tenant_id,)
208
+ )
209
+ row = cur.fetchone()
210
+ return self._parse_row(row_to_dict(row))
211
+
212
+ def get_tenant_by_slug(self, slug: str) -> Optional[Dict[str, Any]]:
213
+ """Get a tenant by slug."""
214
+ from ..core.db import transaction, PH, row_to_dict
215
+ with transaction() as (_conn, cur):
216
+ cur.execute(
217
+ f"SELECT * FROM tenants WHERE slug = {PH}", (slug,)
218
+ )
219
+ row = cur.fetchone()
220
+ return self._parse_row(row_to_dict(row))
221
+
222
+ def list_tenants(self) -> List[Dict[str, Any]]:
223
+ """List all tenants."""
224
+ from ..core.db import transaction, row_to_dict
225
+ with transaction() as (_conn, cur):
226
+ cur.execute("SELECT * FROM tenants ORDER BY created_at")
227
+ rows = cur.fetchall()
228
+ return [
229
+ self._parse_row(row_to_dict(r))
230
+ for r in rows
231
+ if row_to_dict(r) is not None
232
+ ]
233
+
234
+ def update_tenant(self, tenant_id: str, **updates) -> Optional[Dict[str, Any]]:
235
+ """Update tenant fields. Allowed: name, plan, settings, is_active."""
236
+ import json
237
+ from ..core.db import transaction, PH
238
+
239
+ allowed = {"name", "plan", "settings", "is_active"}
240
+ filtered = {k: v for k, v in updates.items() if k in allowed}
241
+ if not filtered:
242
+ return self.get_tenant(tenant_id)
243
+
244
+ # Serialize settings to JSON if present
245
+ if "settings" in filtered and isinstance(filtered["settings"], dict):
246
+ filtered["settings"] = json.dumps(filtered["settings"])
247
+
248
+ now = datetime.now(timezone.utc).isoformat()
249
+ filtered["updated_at"] = now
250
+
251
+ set_clauses = ", ".join(f"{k} = {PH}" for k in filtered)
252
+ values = list(filtered.values()) + [tenant_id]
253
+
254
+ with transaction() as (_conn, cur):
255
+ cur.execute(
256
+ f"UPDATE tenants SET {set_clauses} WHERE id = {PH}",
257
+ tuple(values),
258
+ )
259
+
260
+ return self.get_tenant(tenant_id)
261
+
262
+ def suspend_tenant(self, tenant_id: str, reason: str = "") -> Optional[Dict[str, Any]]:
263
+ """Suspend a tenant (block all access)."""
264
+ from ..core.db import transaction, PH
265
+
266
+ now = datetime.now(timezone.utc).isoformat()
267
+ with transaction() as (_conn, cur):
268
+ cur.execute(
269
+ f"UPDATE tenants SET suspended = {PH}, suspend_reason = {PH}, "
270
+ f"updated_at = {PH} WHERE id = {PH}",
271
+ (True if self._is_pg else 1, reason, now, tenant_id),
272
+ )
273
+
274
+ logger.warning("Tenant %s suspended: %s", tenant_id, reason)
275
+ return self.get_tenant(tenant_id)
276
+
277
+ def get_or_create_default(self) -> Dict[str, Any]:
278
+ """Get or create the default 'dev' tenant (for development mode)."""
279
+ existing = self.get_tenant_by_slug(DEFAULT_TENANT_SLUG)
280
+ if existing:
281
+ return existing
282
+
283
+ return self.create_tenant(
284
+ name=DEFAULT_TENANT_NAME,
285
+ slug=DEFAULT_TENANT_SLUG,
286
+ plan="free",
287
+ )
288
+
289
+ # ── Middleware helper ────────────────────────────────────────────────────
290
+
291
+ def ensure_tenant_context(self, tenant_id: str) -> Dict[str, Any]:
292
+ """Validate that the tenant exists and is active. Returns tenant dict.
293
+
294
+ Raises HTTPException if tenant is not found or suspended.
295
+ Called by middleware to set the current tenant on the request.
296
+ """
297
+ tenant = self.get_tenant(tenant_id)
298
+ if not tenant:
299
+ raise HTTPException(status_code=404, detail="Tenant not found")
300
+ if tenant.get("suspended"):
301
+ raise HTTPException(
302
+ status_code=403,
303
+ detail=f"Tenant suspended: {tenant.get('suspend_reason', 'Contact support')}",
304
+ )
305
+ if not tenant.get("is_active"):
306
+ raise HTTPException(status_code=403, detail="Tenant is inactive")
307
+ return tenant
308
+
309
+ # ── Internal helpers ─────────────────────────────────────────────────────
310
+
311
+ @staticmethod
312
+ def _parse_row(row: Optional[Dict]) -> Optional[Dict[str, Any]]:
313
+ """Parse a raw DB row into a clean tenant dict."""
314
+ if row is None:
315
+ return None
316
+ import json
317
+ result = dict(row)
318
+ # Parse settings JSON
319
+ if isinstance(result.get("settings"), str):
320
+ try:
321
+ result["settings"] = json.loads(result["settings"])
322
+ except (json.JSONDecodeError, TypeError):
323
+ result["settings"] = {}
324
+ # Normalize booleans (SQLite stores as 0/1)
325
+ for key in ("is_active", "suspended"):
326
+ if key in result:
327
+ result[key] = bool(result[key])
328
+ return result
329
+
330
+
331
+ # ── Tenant middleware ────────────────────────────────────────────────────────
332
+
333
+ _tenant_manager: Optional[TenantManager] = None
334
+
335
+
336
+ def _get_tenant_manager() -> TenantManager:
337
+ """Lazy singleton for TenantManager."""
338
+ global _tenant_manager
339
+ if _tenant_manager is None:
340
+ _tenant_manager = TenantManager()
341
+ return _tenant_manager
342
+
343
+
344
+ def _is_production() -> bool:
345
+ return os.environ.get("CONTEXTSYNAPSE_ENV") or os.environ.get("AICONTEXTDB_ENV", "").lower() == "production"
346
+
347
+
348
+ async def tenant_middleware(request: Request, call_next):
349
+ """Extract tenant from JWT and set on request state.
350
+
351
+ In dev mode: use default tenant.
352
+ In production: extract from JWT, validate tenant is active.
353
+ """
354
+ # Skip tenant check for health/docs endpoints
355
+ path = request.url.path
356
+ if path in ("/health", "/docs", "/openapi.json", "/redoc"):
357
+ response = await call_next(request)
358
+ return response
359
+
360
+ tm = _get_tenant_manager()
361
+
362
+ if not _is_production():
363
+ # Dev mode: use default tenant
364
+ default = tm.get_or_create_default()
365
+ request.state.tenant_id = default["id"]
366
+ request.state.tenant = default
367
+ response = await call_next(request)
368
+ return response
369
+
370
+ # Production: extract tenant from JWT claims (set by auth middleware)
371
+ tenant_id = None
372
+
373
+ # Check if auth middleware already set the tenant
374
+ if hasattr(request.state, "tenant_id") and request.state.tenant_id:
375
+ tenant_id = request.state.tenant_id
376
+ else:
377
+ # Try extracting from Authorization header JWT
378
+ auth_header = request.headers.get("Authorization", "")
379
+ if auth_header.startswith("Bearer "):
380
+ token = auth_header[7:]
381
+ try:
382
+ from ..api.auth import verify_jwt
383
+ payload = verify_jwt(token)
384
+ if payload:
385
+ tenant_id = payload.get("tenant") or payload.get("tenant_id")
386
+ except Exception:
387
+ pass
388
+
389
+ if not tenant_id:
390
+ raise HTTPException(
391
+ status_code=401,
392
+ detail="Tenant context required. Include tenant in JWT.",
393
+ )
394
+
395
+ # Validate tenant is active and not suspended
396
+ tenant = tm.ensure_tenant_context(tenant_id)
397
+ request.state.tenant_id = tenant_id
398
+ request.state.tenant = tenant
399
+
400
+ response = await call_next(request)
401
+ return response
@@ -0,0 +1,21 @@
1
+ """AgentShield — continuous behavioral auth + adaptive trust."""
2
+ from __future__ import annotations
3
+
4
+ _shield = None
5
+
6
+ def get_agent_shield():
7
+ global _shield
8
+ if _shield is None:
9
+ redis_client = None
10
+ try:
11
+ import os, redis
12
+ url = os.environ.get("CONTEXTSYNAPSE_REDIS_URL") or os.environ.get("AICONTEXTDB_REDIS_URL")
13
+ if url:
14
+ redis_client = redis.from_url(url)
15
+ except Exception:
16
+ pass
17
+ from .shield import AgentShield
18
+ _shield = AgentShield(redis_client=redis_client)
19
+ return _shield
20
+
21
+ __all__ = ["get_agent_shield"]
@@ -0,0 +1,56 @@
1
+ """AnomalyDetector — statistical anomaly detection for agent behavior."""
2
+ from __future__ import annotations
3
+ import json, math
4
+ from dataclasses import dataclass, field
5
+ from typing import Any, Dict, List
6
+
7
+ @dataclass
8
+ class AnomalyResult:
9
+ score: float = 0.0
10
+ flags: List[str] = field(default_factory=list)
11
+ details: Dict[str, Any] = field(default_factory=dict)
12
+ frozen: bool = False
13
+
14
+ class AnomalyDetector:
15
+ MIN_TOOL_CALLS = 20
16
+ MIN_SESSIONS = 2
17
+
18
+ def analyze(self, profile: Dict, session: Dict) -> AnomalyResult:
19
+ if profile.get("total_tool_calls", 0) < self.MIN_TOOL_CALLS:
20
+ return AnomalyResult()
21
+ if profile.get("sessions_count", 0) < self.MIN_SESSIONS:
22
+ return AnomalyResult()
23
+ flags = []
24
+ details = {}
25
+ hist_dist = json.loads(profile.get("tool_distribution", "{}"))
26
+ sess_dist = json.loads(session.get("tool_distribution", "{}"))
27
+ if hist_dist and sess_dist:
28
+ divergence = self._cosine_distance(hist_dist, sess_dist)
29
+ if divergence > 0.6:
30
+ flags.append("tool_pattern_change")
31
+ details["tool_divergence"] = round(divergence, 3)
32
+ hist_quality = profile.get("feedback_quality", 0.5)
33
+ sess_quality = session.get("feedback_quality")
34
+ if sess_quality is not None and profile.get("total_feedback_given", 0) > 10:
35
+ if sess_quality < hist_quality - 0.3:
36
+ flags.append("quality_drop")
37
+ details["quality_delta"] = round(sess_quality - hist_quality, 3)
38
+ hist_ratio = profile.get("read_write_ratio", 0.5)
39
+ sess_ratio = session.get("read_write_ratio")
40
+ if sess_ratio is not None:
41
+ if abs(sess_ratio - hist_ratio) > 0.4:
42
+ flags.append("unusual_read_scope")
43
+ details["ratio_delta"] = round(sess_ratio - hist_ratio, 3)
44
+ weights = {"tool_pattern_change": 0.35, "quality_drop": 0.30, "unusual_read_scope": 0.20}
45
+ score = min(sum(weights.get(f, 0.15) for f in flags), 1.0)
46
+ return AnomalyResult(score=round(score, 3), flags=flags, details=details, frozen=score >= 0.7)
47
+
48
+ @staticmethod
49
+ def _cosine_distance(a: Dict[str, int], b: Dict[str, int]) -> float:
50
+ all_keys = set(a) | set(b)
51
+ if not all_keys:
52
+ return 0.0
53
+ dot = sum(a.get(k, 0) * b.get(k, 0) for k in all_keys)
54
+ mag_a = math.sqrt(sum(v ** 2 for v in a.values())) or 1.0
55
+ mag_b = math.sqrt(sum(v ** 2 for v in b.values())) or 1.0
56
+ return round(1.0 - dot / (mag_a * mag_b), 4)
@@ -0,0 +1,99 @@
1
+ """AdaptivePermissions — map trust levels to tool access tiers."""
2
+ from __future__ import annotations
3
+ from dataclasses import dataclass
4
+ from typing import Dict, Set
5
+
6
+ TIER_READ = {
7
+ "search_nodes", "get_context", "orient", "briefing", "ask", "recall",
8
+ "graph_summary", "query_graph", "rag_query", "rag_graph", "graph_timeline",
9
+ "graph_diff", "check_freshness", "get_suggestions", "project_status",
10
+ "list_tasks", "my_tasks", "get_agent_context", "get_unblocked_tasks",
11
+ "task_context", "ws_read_file", "ws_list_files", "ws_git_status",
12
+ "a2a_discover", "a2a_get_task", "my_usage", "boundary_costs", "get_tool_policy",
13
+ "explain_context", "topic_scan", "check_reviews", "trace_lineage",
14
+ "search", "code_project_status", "list_pipelines", "list_schemas",
15
+ "get_versions", "get_context_meta",
16
+ }
17
+
18
+ TIER_WRITE = TIER_READ | {
19
+ "add_knowledge", "add_relationship", "add_decision", "add_task",
20
+ "claim_task", "complete_task", "handoff_task", "log_action",
21
+ "remember", "rate_context", "detect_conflicts", "resolve_conflict",
22
+ "report_external", "report_tokens", "a2a_send_task", "a2a_cancel_task",
23
+ "invalidate_node", "request_review", "request_promotion",
24
+ }
25
+
26
+ TIER_FULL = TIER_WRITE | {
27
+ "dispatch_goal", "generate_tasks",
28
+ "ws_write_file", "ws_commit", "ws_push", "ws_create_branch", "ws_run_command",
29
+ "use_graph", "save_schema", "run_pipeline",
30
+ }
31
+
32
+ @dataclass
33
+ class PermissionDecision:
34
+ allowed: bool
35
+ reason: str = ""
36
+
37
+ class AdaptivePermissions:
38
+ def __init__(self):
39
+ self._frozen: Set[str] = set()
40
+ self._active: Dict[str, str] = {} # agent_id -> task_id (mid-workflow)
41
+ self._pending_restrictions: Dict[str, str] = {} # agent_id -> reason (apply after task)
42
+
43
+ def check(self, agent_id: str, tool_name: str, trust_score: float = 0.5) -> PermissionDecision:
44
+ # Grace period: if agent is mid-task, allow but warn
45
+ if agent_id in self._active:
46
+ is_restricted = (agent_id in self._frozen) or (trust_score < 0.2 and tool_name not in TIER_READ)
47
+ if is_restricted:
48
+ reason = "frozen" if agent_id in self._frozen else f"low trust ({trust_score:.2f})"
49
+ self._pending_restrictions[agent_id] = reason
50
+ return PermissionDecision(True, f"WARNING: {reason} — restrictions apply after current task completes")
51
+ # Normal permission check for active agents
52
+ return self._check_tier(agent_id, tool_name, trust_score)
53
+
54
+ # Not active — enforce restrictions immediately
55
+ # But first check if there's a pending restriction from a completed task
56
+ if agent_id in self._pending_restrictions:
57
+ if tool_name == "claim_task":
58
+ # Block new task claims — restrictions are now active
59
+ reason = self._pending_restrictions.pop(agent_id)
60
+ return PermissionDecision(False, f"Restricted: {reason}")
61
+
62
+ return self._check_tier(agent_id, tool_name, trust_score)
63
+
64
+ def _check_tier(self, agent_id: str, tool_name: str, trust_score: float) -> PermissionDecision:
65
+ if agent_id in self._frozen:
66
+ if tool_name in TIER_READ:
67
+ return PermissionDecision(True, "read-only (frozen)")
68
+ return PermissionDecision(False, "Agent frozen — anomaly detected")
69
+ if trust_score >= 0.8:
70
+ return PermissionDecision(True, "trusted")
71
+ if trust_score >= 0.5:
72
+ if tool_name in TIER_FULL:
73
+ return PermissionDecision(True, "verified")
74
+ return PermissionDecision(False, f"Requires trust >= 0.8 (current: {trust_score:.2f})")
75
+ if trust_score >= 0.2:
76
+ if tool_name in TIER_WRITE:
77
+ return PermissionDecision(True, "provisional")
78
+ return PermissionDecision(False, f"Requires trust >= 0.5 (current: {trust_score:.2f})")
79
+ if tool_name in TIER_READ:
80
+ return PermissionDecision(True, "untrusted: read-only")
81
+ return PermissionDecision(False, "Untrusted agent: read-only access")
82
+
83
+ def mark_active(self, agent_id: str, task_id: str):
84
+ """Mark agent as mid-workflow (won't be blocked until task completes)."""
85
+ self._active[agent_id] = task_id
86
+
87
+ def mark_idle(self, agent_id: str):
88
+ """Mark agent as idle (restrictions now enforced)."""
89
+ self._active.pop(agent_id, None)
90
+
91
+ def freeze(self, agent_id: str):
92
+ self._frozen.add(agent_id)
93
+
94
+ def unfreeze(self, agent_id: str):
95
+ self._frozen.discard(agent_id)
96
+ self._pending_restrictions.pop(agent_id, None)
97
+
98
+ def is_frozen(self, agent_id: str) -> bool:
99
+ return agent_id in self._frozen
@@ -0,0 +1,103 @@
1
+ """AgentProfile — behavioral fingerprint per agent."""
2
+ from __future__ import annotations
3
+ import json, logging
4
+ from datetime import datetime, timezone
5
+ from typing import Any, Dict, Optional
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+ _DEFAULT_PROFILE = {
10
+ "total_reads": 0, "total_writes": 0, "total_tool_calls": 0,
11
+ "total_feedback_given": 0, "total_derivations": 0,
12
+ "feedback_useful": 0, "feedback_misleading": 0, "feedback_incorrect": 0, "feedback_outdated": 0,
13
+ "invalidations_caused": 0, "read_write_ratio": 0.5, "feedback_quality": 0.5,
14
+ "tool_distribution": "{}", "hour_distribution": "{}",
15
+ "sessions_count": 0, "consecutive_clean": 0,
16
+ }
17
+
18
+ class AgentProfile:
19
+ def __init__(self, redis_client=None):
20
+ self._redis = redis_client
21
+ self._memory: Dict[str, Dict[str, Any]] = {}
22
+ self._prefix = "contextcore:shield:profile"
23
+
24
+ def get(self, agent_id: str) -> Dict[str, Any]:
25
+ if self._redis:
26
+ try:
27
+ key = f"{self._prefix}:{agent_id}"
28
+ raw = self._redis.hgetall(key)
29
+ if raw:
30
+ data = dict(_DEFAULT_PROFILE)
31
+ for k, v in raw.items():
32
+ k = k.decode() if isinstance(k, bytes) else k
33
+ v = v.decode() if isinstance(v, bytes) else v
34
+ if k in data and isinstance(data[k], (int, float)):
35
+ data[k] = type(data[k])(v)
36
+ else:
37
+ data[k] = v
38
+ return data
39
+ except Exception:
40
+ pass
41
+ return dict(self._memory.get(agent_id, _DEFAULT_PROFILE))
42
+
43
+ def record_event(self, agent_id: str, event_type: str):
44
+ d = self._ensure(agent_id)
45
+ if event_type == "read":
46
+ d["total_reads"] += 1
47
+ elif event_type in ("write", "derive"):
48
+ d["total_writes"] += 1
49
+ if event_type == "derive":
50
+ d["total_derivations"] += 1
51
+ total = d["total_reads"] + d["total_writes"]
52
+ d["read_write_ratio"] = round(d["total_reads"] / total, 3) if total > 0 else 0.5
53
+ self._save(agent_id, d)
54
+
55
+ def record_tool_call(self, agent_id: str, tool_name: str):
56
+ d = self._ensure(agent_id)
57
+ d["total_tool_calls"] += 1
58
+ dist = json.loads(d["tool_distribution"])
59
+ dist[tool_name] = dist.get(tool_name, 0) + 1
60
+ d["tool_distribution"] = json.dumps(dist)
61
+ hour = str(datetime.now(timezone.utc).hour)
62
+ hours = json.loads(d["hour_distribution"])
63
+ hours[hour] = hours.get(hour, 0) + 1
64
+ d["hour_distribution"] = json.dumps(hours)
65
+ self._save(agent_id, d)
66
+
67
+ def record_feedback(self, agent_id: str, signal: str):
68
+ d = self._ensure(agent_id)
69
+ d["total_feedback_given"] += 1
70
+ key = f"feedback_{signal}"
71
+ if key in d:
72
+ d[key] += 1
73
+ good = d["feedback_useful"]
74
+ bad = d["feedback_misleading"] + d["feedback_incorrect"] + d["feedback_outdated"]
75
+ total = good + bad
76
+ d["feedback_quality"] = round(good / total, 3) if total > 0 else 0.5
77
+ if signal in ("misleading", "incorrect"):
78
+ d["consecutive_clean"] = 0
79
+ self._save(agent_id, d)
80
+
81
+ def record_invalidation(self, agent_id: str, count: int = 1):
82
+ d = self._ensure(agent_id)
83
+ d["invalidations_caused"] += count
84
+ d["consecutive_clean"] = 0
85
+ self._save(agent_id, d)
86
+
87
+ def increment_clean(self, agent_id: str):
88
+ d = self._ensure(agent_id)
89
+ d["consecutive_clean"] += 1
90
+ self._save(agent_id, d)
91
+
92
+ def _ensure(self, agent_id: str) -> Dict[str, Any]:
93
+ if agent_id not in self._memory:
94
+ self._memory[agent_id] = dict(_DEFAULT_PROFILE)
95
+ return self._memory[agent_id]
96
+
97
+ def _save(self, agent_id: str, data: Dict):
98
+ self._memory[agent_id] = data
99
+ if self._redis:
100
+ try:
101
+ self._redis.hset(f"{self._prefix}:{agent_id}", mapping={k: str(v) for k, v in data.items()})
102
+ except Exception:
103
+ pass