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,270 @@
1
+ """
2
+ Context Quality Tracker
3
+ ========================
4
+ Measures whether context delivered to agents was actually useful.
5
+
6
+ Tracks: what was delivered → what the agent did next → was context referenced?
7
+
8
+ Metrics:
9
+ - relevance_score: Did the agent's next actions relate to delivered content?
10
+ - freshness_score: How old were the delivered nodes?
11
+ - coverage_score: What percentage of the graph was represented?
12
+ - waste_ratio: Tokens delivered but never referenced by agent actions.
13
+
14
+ Usage::
15
+
16
+ tracker = ContextQualityTracker()
17
+
18
+ # When context is delivered
19
+ tracker.record_delivery("agent-1", ["node-a", "node-b"], token_count=2000)
20
+
21
+ # After each agent tool call
22
+ tracker.record_agent_action("agent-1", "search_nodes", {"query": "AQI"})
23
+
24
+ # Compute quality
25
+ report = tracker.compute_quality("agent-1")
26
+ print(report.relevance_score, report.waste_ratio)
27
+ """
28
+
29
+ from __future__ import annotations
30
+
31
+ import logging
32
+ import time
33
+ from collections import defaultdict
34
+ from dataclasses import dataclass, field
35
+ from typing import Any, Dict, List, Optional
36
+
37
+ logger = logging.getLogger(__name__)
38
+
39
+
40
+ @dataclass
41
+ class ContextDelivery:
42
+ """Record of context delivered to an agent."""
43
+ delivery_id: str
44
+ agent_id: str
45
+ timestamp: float
46
+ node_ids: List[str]
47
+ node_labels: List[str]
48
+ token_count: int
49
+ total_graph_nodes: int = 0
50
+
51
+
52
+ @dataclass
53
+ class AgentAction:
54
+ """Record of what an agent did after receiving context."""
55
+ agent_id: str
56
+ timestamp: float
57
+ tool_name: str
58
+ params: Dict[str, Any]
59
+ keywords: List[str] = field(default_factory=list)
60
+
61
+
62
+ @dataclass
63
+ class ContextUsageReport:
64
+ """Quality metrics for context delivery."""
65
+ relevance_score: float = 0.0 # 0-1: did agent's actions relate to delivered content?
66
+ freshness_score: float = 0.0 # 0-1: how fresh were delivered nodes?
67
+ coverage_score: float = 0.0 # 0-1: what % of graph was represented?
68
+ waste_ratio: float = 0.0 # 0-1: tokens not referenced (higher = more waste)
69
+ deliveries_count: int = 0
70
+ actions_count: int = 0
71
+ total_tokens_delivered: int = 0
72
+
73
+ def to_dict(self) -> Dict[str, Any]:
74
+ return {
75
+ "relevance_score": round(self.relevance_score, 3),
76
+ "freshness_score": round(self.freshness_score, 3),
77
+ "coverage_score": round(self.coverage_score, 3),
78
+ "waste_ratio": round(self.waste_ratio, 3),
79
+ "deliveries_count": self.deliveries_count,
80
+ "actions_count": self.actions_count,
81
+ "total_tokens_delivered": self.total_tokens_delivered,
82
+ }
83
+
84
+
85
+ class ContextQualityTracker:
86
+ """Tracks context deliveries and agent actions to compute quality metrics."""
87
+
88
+ def __init__(self, window_seconds: int = 600):
89
+ self._window = window_seconds
90
+ # agent_id → list of deliveries
91
+ self._deliveries: Dict[str, List[ContextDelivery]] = defaultdict(list)
92
+ # agent_id → list of actions
93
+ self._actions: Dict[str, List[AgentAction]] = defaultdict(list)
94
+ self._delivery_counter = 0
95
+
96
+ def record_delivery(
97
+ self,
98
+ agent_id: str,
99
+ node_ids: List[str],
100
+ token_count: int,
101
+ node_labels: Optional[List[str]] = None,
102
+ total_graph_nodes: int = 0,
103
+ ) -> str:
104
+ """Record a context delivery to an agent.
105
+
106
+ Called when ContextHub exports context (to_prompt, to_messages).
107
+ """
108
+ self._delivery_counter += 1
109
+ did = f"del_{self._delivery_counter}"
110
+ delivery = ContextDelivery(
111
+ delivery_id=did,
112
+ agent_id=agent_id,
113
+ timestamp=time.time(),
114
+ node_ids=node_ids or [],
115
+ node_labels=node_labels or [],
116
+ token_count=token_count,
117
+ total_graph_nodes=total_graph_nodes,
118
+ )
119
+ self._deliveries[agent_id].append(delivery)
120
+ self._prune(agent_id)
121
+ return did
122
+
123
+ def record_agent_action(
124
+ self,
125
+ agent_id: str,
126
+ tool_name: str,
127
+ params: Dict[str, Any],
128
+ ):
129
+ """Record an agent tool call after context delivery.
130
+
131
+ Called after ToolRegistry.dispatch() to track what agent did with context.
132
+ """
133
+ # Extract keywords from tool params for relevance matching
134
+ keywords = []
135
+ for v in params.values():
136
+ if isinstance(v, str) and len(v) > 2:
137
+ keywords.extend(w.lower() for w in v.split() if len(w) > 2)
138
+
139
+ action = AgentAction(
140
+ agent_id=agent_id,
141
+ timestamp=time.time(),
142
+ tool_name=tool_name,
143
+ params=params,
144
+ keywords=keywords,
145
+ )
146
+ self._actions[agent_id].append(action)
147
+ self._prune(agent_id)
148
+
149
+ def compute_quality(
150
+ self,
151
+ agent_id: str,
152
+ window_seconds: Optional[int] = None,
153
+ ) -> ContextUsageReport:
154
+ """Compute quality metrics for an agent's recent context deliveries.
155
+
156
+ Metrics:
157
+ - relevance: keyword overlap between delivered node content and agent actions
158
+ - freshness: average age of delivered nodes (inverse of staleness)
159
+ - coverage: ratio of delivered nodes to total graph nodes
160
+ - waste: ratio of tokens in nodes never referenced by agent actions
161
+ """
162
+ window = window_seconds or self._window
163
+ cutoff = time.time() - window
164
+
165
+ deliveries = [d for d in self._deliveries.get(agent_id, []) if d.timestamp > cutoff]
166
+ actions = [a for a in self._actions.get(agent_id, []) if a.timestamp > cutoff]
167
+
168
+ if not deliveries:
169
+ return ContextUsageReport()
170
+
171
+ # ── Relevance: do agent actions reference delivered content? ──
172
+ delivered_node_ids = set()
173
+ delivered_labels = set()
174
+ for d in deliveries:
175
+ delivered_node_ids.update(d.node_ids)
176
+ delivered_labels.update(d.node_labels)
177
+
178
+ # Check if agent searched for labels/content that was delivered
179
+ action_keywords = set()
180
+ action_labels = set()
181
+ for a in actions:
182
+ action_keywords.update(a.keywords)
183
+ label = a.params.get("label", "")
184
+ if label:
185
+ action_labels.add(label.lower())
186
+
187
+ # Relevance = overlap between delivered labels and action labels/keywords
188
+ delivered_labels_lower = {l.lower() for l in delivered_labels}
189
+ if delivered_labels_lower:
190
+ label_overlap = len(delivered_labels_lower & action_labels) / len(delivered_labels_lower)
191
+ else:
192
+ label_overlap = 0.0
193
+
194
+ # Also check keyword overlap between delivered node IDs mentioned in params
195
+ node_refs = sum(1 for a in actions for v in a.params.values()
196
+ if isinstance(v, str) and any(nid[:8] in v for nid in delivered_node_ids))
197
+ node_ref_ratio = min(1.0, node_refs / max(len(delivered_node_ids), 1))
198
+
199
+ relevance = (label_overlap * 0.6 + node_ref_ratio * 0.4)
200
+
201
+ # ── Freshness: how recent were deliveries? ──
202
+ now = time.time()
203
+ ages = [now - d.timestamp for d in deliveries]
204
+ avg_age = sum(ages) / len(ages) if ages else 0
205
+ # Normalize: 0 age = 1.0 freshness, window age = 0.0
206
+ freshness = max(0.0, 1.0 - (avg_age / window))
207
+
208
+ # ── Coverage: what % of graph was represented? ──
209
+ total_graph = max(d.total_graph_nodes for d in deliveries) if deliveries else 0
210
+ if total_graph > 0:
211
+ coverage = min(1.0, len(delivered_node_ids) / total_graph)
212
+ else:
213
+ coverage = 0.0
214
+
215
+ # ── Waste: tokens delivered but agent didn't use ──
216
+ total_tokens = sum(d.token_count for d in deliveries)
217
+ # If agent took no actions after delivery, waste = 1.0
218
+ # If agent referenced all content, waste = 0.0
219
+ if not actions:
220
+ waste = 1.0
221
+ else:
222
+ # Estimate: if agent only searched for 1 label out of 5 delivered, waste = 0.8
223
+ used_fraction = relevance # reuse relevance as proxy for usage
224
+ waste = max(0.0, 1.0 - used_fraction)
225
+
226
+ return ContextUsageReport(
227
+ relevance_score=round(relevance, 3),
228
+ freshness_score=round(freshness, 3),
229
+ coverage_score=round(coverage, 3),
230
+ waste_ratio=round(waste, 3),
231
+ deliveries_count=len(deliveries),
232
+ actions_count=len(actions),
233
+ total_tokens_delivered=total_tokens,
234
+ )
235
+
236
+ def get_quality_timeline(
237
+ self,
238
+ experiment_id: str = "",
239
+ agent_ids: Optional[List[str]] = None,
240
+ ) -> List[Dict[str, Any]]:
241
+ """Get quality scores for dashboard visualization."""
242
+ results = []
243
+ target_agents = agent_ids or list(self._deliveries.keys())
244
+ for aid in target_agents:
245
+ report = self.compute_quality(aid)
246
+ if report.deliveries_count > 0:
247
+ results.append({
248
+ "agent_id": aid,
249
+ "experiment_id": experiment_id,
250
+ **report.to_dict(),
251
+ })
252
+ return results
253
+
254
+ def _prune(self, agent_id: str):
255
+ """Remove entries older than the window."""
256
+ cutoff = time.time() - self._window
257
+ self._deliveries[agent_id] = [d for d in self._deliveries[agent_id] if d.timestamp > cutoff]
258
+ self._actions[agent_id] = [a for a in self._actions[agent_id] if a.timestamp > cutoff]
259
+
260
+
261
+ # Global singleton
262
+ _tracker: Optional[ContextQualityTracker] = None
263
+
264
+
265
+ def get_quality_tracker() -> ContextQualityTracker:
266
+ """Get or create the global quality tracker."""
267
+ global _tracker
268
+ if _tracker is None:
269
+ _tracker = ContextQualityTracker()
270
+ return _tracker
@@ -0,0 +1,370 @@
1
+ """
2
+ Context Scoping
3
+ ================
4
+ Token budget enforcement and priority ranking for context items.
5
+
6
+ When a ContextHub has more content than fits in a model's context window,
7
+ the scoper selects the most valuable items within a token budget.
8
+
9
+ Usage::
10
+
11
+ from contextsynapse.context.scoping import ContextScoper, ScopingConfig
12
+
13
+ scoper = ContextScoper(ScopingConfig(max_tokens=4000, strategy="combined"))
14
+ selected = scoper.select_within_budget(hub.items(), max_tokens=4000)
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import logging
20
+ from dataclasses import dataclass, field
21
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING
22
+
23
+ if TYPE_CHECKING:
24
+ from .hub import ContextItem, ContextRole
25
+
26
+ logger = logging.getLogger(__name__)
27
+
28
+ # Optional tiktoken for accurate token counts
29
+ _tiktoken_available = False
30
+ _tiktoken_encoding = None
31
+ try:
32
+ import tiktoken
33
+ _tiktoken_encoding = tiktoken.get_encoding("cl100k_base")
34
+ _tiktoken_available = True
35
+ except Exception:
36
+ pass
37
+
38
+
39
+ # Default role weights — higher = more important to keep
40
+ DEFAULT_ROLE_WEIGHTS: Dict[str, float] = {
41
+ "system": 10.0,
42
+ "instruction": 9.0,
43
+ "decision": 8.0,
44
+ "feedback": 7.5, # human corrections are high-value
45
+ "synthesis": 7.0,
46
+ "human": 6.5, # explicit human-provided context
47
+ "retrieved": 6.0,
48
+ "document": 5.5, # full source documents
49
+ "background": 5.0,
50
+ "tool": 4.5, # tool call results
51
+ "interaction": 4.0, # multi-turn dialogue transcripts
52
+ "example": 4.0,
53
+ "generated": 3.0,
54
+ "user": 2.0,
55
+ "assistant": 1.0,
56
+ }
57
+
58
+
59
+ @dataclass
60
+ class ScopingConfig:
61
+ """Configuration for token budget enforcement."""
62
+ max_tokens: int = 8000
63
+ strategy: str = "combined" # recency | relevance | role_priority | combined
64
+ role_weights: Dict[str, float] = field(default_factory=lambda: dict(DEFAULT_ROLE_WEIGHTS))
65
+ recency_decay: float = 0.95 # multiplier per position from newest
66
+ reserve_system: bool = True # always keep system messages
67
+ reserve_ratio: float = 0.1 # fraction of budget reserved for system messages
68
+ # Combined strategy weights
69
+ role_weight_factor: float = 0.3
70
+ recency_factor: float = 0.3
71
+ relevance_factor: float = 0.4
72
+ confidence_factor: float = 0.0 # opt-in: weight of confidence in combined scoring
73
+ # Custom per-label or per-tag boosts
74
+ custom_weights: Dict[str, float] = field(default_factory=dict)
75
+
76
+
77
+ @dataclass
78
+ class ScoredItem:
79
+ """A context item annotated with its priority score and token estimate."""
80
+ item: Any # ContextItem
81
+ index: int # original position in the list
82
+ score: float = 0.0
83
+ token_estimate: int = 0
84
+ breakdown: Dict = None # {"role": 0.27, "recency": 0.25, "relevance": 0.38, "confidence": 0.10}
85
+ reason: str = "" # human-readable: "relevance (0.38) + role (0.27)"
86
+
87
+ def __post_init__(self):
88
+ if self.breakdown is None:
89
+ self.breakdown = {}
90
+
91
+
92
+ class ContextScoper:
93
+ """
94
+ Score and select context items within a token budget.
95
+
96
+ Strategies:
97
+ - **recency**: Newer items (later in list) score higher.
98
+ - **role_priority**: Items with important roles (system, instruction) score higher.
99
+ - **relevance**: External relevance scores (e.g., from vector similarity).
100
+ - **combined**: Weighted mix of all three.
101
+ """
102
+
103
+ def __init__(self, config: Optional[ScopingConfig] = None):
104
+ self.config = config or ScopingConfig()
105
+
106
+ def estimate_tokens(self, text: str) -> int:
107
+ """Estimate token count for a string."""
108
+ if _tiktoken_available and _tiktoken_encoding is not None:
109
+ return len(_tiktoken_encoding.encode(text))
110
+ return max(1, int(len(text) / 4.0))
111
+
112
+ @staticmethod
113
+ def _compute_query_relevance(query: str, items: List[Any]) -> Dict[int, float]:
114
+ """Compute keyword-overlap relevance between a query and each item.
115
+
116
+ Returns a dict of {item_index: score} where score is in [0, 1].
117
+ Uses normalized keyword intersection — lightweight, no embeddings needed.
118
+ """
119
+ _STOP_WORDS = frozenset({
120
+ "the", "a", "an", "is", "are", "was", "were", "be", "been", "being",
121
+ "have", "has", "had", "do", "does", "did", "will", "would", "could",
122
+ "should", "may", "might", "shall", "can", "need", "dare", "ought",
123
+ "this", "that", "these", "those", "i", "you", "he", "she", "it",
124
+ "we", "they", "what", "which", "who", "whom", "how", "where", "when",
125
+ "why", "all", "each", "every", "both", "few", "more", "most", "other",
126
+ "some", "such", "no", "not", "only", "own", "same", "so", "than",
127
+ "too", "very", "just", "about", "above", "after", "again", "also",
128
+ "and", "any", "as", "at", "but", "by", "for", "from", "get", "show",
129
+ "find", "tell", "give", "in", "into", "of", "off", "on", "or", "out",
130
+ "to", "up", "with",
131
+ })
132
+ import re as _re
133
+ query_terms = {
134
+ w for w in _re.split(r"\W+", query.lower()) if len(w) > 1 and w not in _STOP_WORDS
135
+ }
136
+ if not query_terms:
137
+ return {}
138
+
139
+ scores: Dict[int, float] = {}
140
+ for i, item in enumerate(items):
141
+ text = item.content.lower() if hasattr(item, "content") else str(item).lower()
142
+ # Count how many query terms appear in the item
143
+ hits = sum(1 for t in query_terms if t in text)
144
+ scores[i] = hits / len(query_terms) # [0.0, 1.0]
145
+ return scores
146
+
147
+ def score_items(
148
+ self,
149
+ items: List[Any],
150
+ query: Optional[str] = None,
151
+ relevance_scores: Optional[Dict[int, float]] = None,
152
+ ) -> List[ScoredItem]:
153
+ """
154
+ Score each item according to the configured strategy.
155
+
156
+ Args:
157
+ items: List of ContextItem objects.
158
+ query: Optional query string for computing relevance scores
159
+ automatically when *relevance_scores* is not provided.
160
+ relevance_scores: Optional dict mapping item index → relevance score [0, 1].
161
+ When omitted and *query* is given, keyword-overlap relevance is
162
+ computed automatically.
163
+
164
+ Returns:
165
+ List of ScoredItem with scores and token estimates.
166
+ """
167
+ n = len(items)
168
+ if n == 0:
169
+ return []
170
+
171
+ scored: List[ScoredItem] = []
172
+ strategy = self.config.strategy
173
+
174
+ # Auto-compute relevance when a query is given but no external scores
175
+ if not relevance_scores and query:
176
+ relevance_scores = self._compute_query_relevance(query, items)
177
+ relevance_scores = relevance_scores or {}
178
+
179
+ for i, item in enumerate(items):
180
+ tokens = self.estimate_tokens(item.content)
181
+ role_val = item.role.value if hasattr(item.role, "value") else str(item.role)
182
+
183
+ # --- Temporal filtering (C3) ---
184
+ item_status = getattr(item, "state", "active")
185
+ if item_status in ("superseded", "expired"):
186
+ scored.append(ScoredItem(item=item, index=i, score=0.0, token_estimate=tokens,
187
+ breakdown={"excluded": 1.0}, reason=f"excluded ({item_status})"))
188
+ continue
189
+ # Check valid_to in metadata
190
+ valid_to = (getattr(item, "metadata", {}) or {}).get("valid_to")
191
+ if valid_to and isinstance(valid_to, str):
192
+ try:
193
+ from datetime import datetime as _dt, timezone as _tz
194
+ if valid_to < _dt.now(_tz.utc).isoformat():
195
+ scored.append(ScoredItem(item=item, index=i, score=0.0, token_estimate=tokens,
196
+ breakdown={"excluded": 1.0}, reason="excluded (expired)"))
197
+ continue
198
+ except Exception:
199
+ pass
200
+
201
+ # --- Recency score ---
202
+ # Use _created_at timestamp if available, otherwise position-based
203
+ recency = self.config.recency_decay ** (n - 1 - i)
204
+ created_at = getattr(item, "created_at", "") or (item.metadata.get("_created_at", "") if hasattr(item, "metadata") else "")
205
+ if created_at:
206
+ try:
207
+ from datetime import datetime, timezone
208
+ import math
209
+ ts = datetime.fromisoformat(created_at.replace("Z", "+00:00"))
210
+ age_h = max(0.01, (datetime.now(timezone.utc) - ts).total_seconds() / 3600)
211
+ # Newer = higher recency (half-life 72 hours)
212
+ recency = math.exp(-0.693 * age_h / 72)
213
+ except Exception:
214
+ pass
215
+
216
+ # --- Role priority score ---
217
+ role_score = self.config.role_weights.get(role_val, 1.0) / 10.0 # normalise to [0, 1]
218
+
219
+ # --- Relevance score ---
220
+ relevance = relevance_scores.get(i, 0.3) # default low when no query match
221
+
222
+ # --- Custom boosts ---
223
+ boost = 0.0
224
+ if item.label and item.label in self.config.custom_weights:
225
+ boost = max(boost, self.config.custom_weights[item.label])
226
+ for tag in getattr(item, "tags", []):
227
+ if tag in self.config.custom_weights:
228
+ boost = max(boost, self.config.custom_weights[tag])
229
+
230
+ # --- Confidence score ---
231
+ conf_score = getattr(item, "confidence", 1.0)
232
+ stale_penalty = 1.0
233
+ if item_status == "stale":
234
+ stale_penalty = 0.5
235
+
236
+ # --- Compute final score + breakdown (C6) ---
237
+ role_component = self.config.role_weight_factor * role_score
238
+ recency_component = self.config.recency_factor * recency
239
+ relevance_component = self.config.relevance_factor * relevance
240
+ confidence_component = self.config.confidence_factor * conf_score
241
+
242
+ if strategy == "recency":
243
+ score = recency * stale_penalty
244
+ elif strategy == "role_priority":
245
+ score = role_score * stale_penalty
246
+ elif strategy == "relevance":
247
+ score = relevance * stale_penalty
248
+ else: # combined
249
+ score = (role_component + recency_component + relevance_component + confidence_component) * stale_penalty
250
+
251
+ score += boost
252
+
253
+ breakdown = {
254
+ "role": round(role_component, 4),
255
+ "recency": round(recency_component, 4),
256
+ "relevance": round(relevance_component, 4),
257
+ "confidence": round(confidence_component, 4),
258
+ }
259
+ sorted_factors = sorted(breakdown.items(), key=lambda x: x[1], reverse=True)
260
+ top_factors = [f"{k} ({v:.2f})" for k, v in sorted_factors[:2] if v > 0]
261
+ reason = " + ".join(top_factors) if top_factors else "default score"
262
+
263
+ scored.append(ScoredItem(
264
+ item=item,
265
+ index=i,
266
+ score=score,
267
+ token_estimate=tokens,
268
+ breakdown=breakdown,
269
+ reason=reason,
270
+ ))
271
+
272
+ return scored
273
+
274
+ def select_within_budget(
275
+ self,
276
+ items: List[Any],
277
+ max_tokens: Optional[int] = None,
278
+ query: Optional[str] = None,
279
+ relevance_scores: Optional[Dict[int, float]] = None,
280
+ ) -> List[Any]:
281
+ """
282
+ Select items that fit within the token budget, prioritised by score.
283
+
284
+ Algorithm:
285
+ 1. Reserve system messages if configured.
286
+ 2. Score remaining items.
287
+ 3. Greedily add highest-scored items until budget is exhausted.
288
+ 4. Return items in their original order.
289
+
290
+ Args:
291
+ items: Full list of ContextItem objects.
292
+ max_tokens: Override budget (defaults to config.max_tokens).
293
+ query: Optional query for relevance scoring.
294
+ relevance_scores: Optional external relevance scores.
295
+
296
+ Returns:
297
+ Subset of items within budget, in original order.
298
+ """
299
+ budget = max_tokens or self.config.max_tokens
300
+
301
+ if not items:
302
+ return []
303
+
304
+ # --- Step 1: Reserve system messages ---
305
+ system_items: List[Any] = []
306
+ other_items: List[Any] = []
307
+ system_indices: set = set()
308
+
309
+ if self.config.reserve_system:
310
+ system_budget = int(budget * self.config.reserve_ratio)
311
+ system_tokens = 0
312
+ for i, item in enumerate(items):
313
+ role_val = item.role.value if hasattr(item.role, "value") else str(item.role)
314
+ if role_val == "system":
315
+ t = self.estimate_tokens(item.content)
316
+ if system_tokens + t <= system_budget or not system_items:
317
+ system_items.append(item)
318
+ system_indices.add(i)
319
+ system_tokens += t
320
+ else:
321
+ other_items.append(item)
322
+ else:
323
+ other_items.append(item)
324
+ remaining_budget = budget - system_tokens
325
+ else:
326
+ other_items = list(items)
327
+ remaining_budget = budget
328
+
329
+ # --- Step 2: Score remaining items ---
330
+ # Build relevance map with adjusted indices for other_items
331
+ adj_relevance: Dict[int, float] = {}
332
+ if relevance_scores:
333
+ other_idx = 0
334
+ for orig_idx in range(len(items)):
335
+ if orig_idx not in system_indices:
336
+ if orig_idx in relevance_scores:
337
+ adj_relevance[other_idx] = relevance_scores[orig_idx]
338
+ other_idx += 1
339
+
340
+ scored = self.score_items(other_items, query=query, relevance_scores=adj_relevance)
341
+
342
+ # --- Step 3: Greedy selection by score ---
343
+ scored.sort(key=lambda s: s.score, reverse=True)
344
+
345
+ selected_indices: set = set()
346
+ used_tokens = 0
347
+ for si in scored:
348
+ if used_tokens + si.token_estimate <= remaining_budget:
349
+ selected_indices.add(si.index)
350
+ used_tokens += si.token_estimate
351
+
352
+ # --- Step 4: Return in original order ---
353
+ selected_other = [other_items[i] for i in sorted(selected_indices)]
354
+
355
+ # Merge system + selected, preserving original interleaving
356
+ result: List[Any] = []
357
+ sys_iter = iter(system_items)
358
+ other_iter = iter(selected_other)
359
+ next_sys = next(sys_iter, None)
360
+ next_other = next(other_iter, None)
361
+
362
+ for item in items:
363
+ if item is next_sys:
364
+ result.append(item)
365
+ next_sys = next(sys_iter, None)
366
+ elif item is next_other:
367
+ result.append(item)
368
+ next_other = next(other_iter, None)
369
+
370
+ return result