attune-ai 2.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 (457) hide show
  1. attune/__init__.py +358 -0
  2. attune/adaptive/__init__.py +13 -0
  3. attune/adaptive/task_complexity.py +127 -0
  4. attune/agent_monitoring.py +414 -0
  5. attune/cache/__init__.py +117 -0
  6. attune/cache/base.py +166 -0
  7. attune/cache/dependency_manager.py +256 -0
  8. attune/cache/hash_only.py +251 -0
  9. attune/cache/hybrid.py +457 -0
  10. attune/cache/storage.py +285 -0
  11. attune/cache_monitor.py +356 -0
  12. attune/cache_stats.py +298 -0
  13. attune/cli/__init__.py +152 -0
  14. attune/cli/__main__.py +12 -0
  15. attune/cli/commands/__init__.py +1 -0
  16. attune/cli/commands/batch.py +264 -0
  17. attune/cli/commands/cache.py +248 -0
  18. attune/cli/commands/help.py +331 -0
  19. attune/cli/commands/info.py +140 -0
  20. attune/cli/commands/inspect.py +436 -0
  21. attune/cli/commands/inspection.py +57 -0
  22. attune/cli/commands/memory.py +48 -0
  23. attune/cli/commands/metrics.py +92 -0
  24. attune/cli/commands/orchestrate.py +184 -0
  25. attune/cli/commands/patterns.py +207 -0
  26. attune/cli/commands/profiling.py +202 -0
  27. attune/cli/commands/provider.py +98 -0
  28. attune/cli/commands/routing.py +285 -0
  29. attune/cli/commands/setup.py +96 -0
  30. attune/cli/commands/status.py +235 -0
  31. attune/cli/commands/sync.py +166 -0
  32. attune/cli/commands/tier.py +121 -0
  33. attune/cli/commands/utilities.py +114 -0
  34. attune/cli/commands/workflow.py +579 -0
  35. attune/cli/core.py +32 -0
  36. attune/cli/parsers/__init__.py +68 -0
  37. attune/cli/parsers/batch.py +118 -0
  38. attune/cli/parsers/cache.py +65 -0
  39. attune/cli/parsers/help.py +41 -0
  40. attune/cli/parsers/info.py +26 -0
  41. attune/cli/parsers/inspect.py +66 -0
  42. attune/cli/parsers/metrics.py +42 -0
  43. attune/cli/parsers/orchestrate.py +61 -0
  44. attune/cli/parsers/patterns.py +54 -0
  45. attune/cli/parsers/provider.py +40 -0
  46. attune/cli/parsers/routing.py +110 -0
  47. attune/cli/parsers/setup.py +42 -0
  48. attune/cli/parsers/status.py +47 -0
  49. attune/cli/parsers/sync.py +31 -0
  50. attune/cli/parsers/tier.py +33 -0
  51. attune/cli/parsers/workflow.py +77 -0
  52. attune/cli/utils/__init__.py +1 -0
  53. attune/cli/utils/data.py +242 -0
  54. attune/cli/utils/helpers.py +68 -0
  55. attune/cli_legacy.py +3957 -0
  56. attune/cli_minimal.py +1159 -0
  57. attune/cli_router.py +437 -0
  58. attune/cli_unified.py +814 -0
  59. attune/config/__init__.py +66 -0
  60. attune/config/xml_config.py +286 -0
  61. attune/config.py +545 -0
  62. attune/coordination.py +870 -0
  63. attune/core.py +1511 -0
  64. attune/core_modules/__init__.py +15 -0
  65. attune/cost_tracker.py +626 -0
  66. attune/dashboard/__init__.py +41 -0
  67. attune/dashboard/app.py +512 -0
  68. attune/dashboard/simple_server.py +435 -0
  69. attune/dashboard/standalone_server.py +547 -0
  70. attune/discovery.py +306 -0
  71. attune/emergence.py +306 -0
  72. attune/exceptions.py +123 -0
  73. attune/feedback_loops.py +373 -0
  74. attune/hot_reload/README.md +473 -0
  75. attune/hot_reload/__init__.py +62 -0
  76. attune/hot_reload/config.py +83 -0
  77. attune/hot_reload/integration.py +229 -0
  78. attune/hot_reload/reloader.py +298 -0
  79. attune/hot_reload/watcher.py +183 -0
  80. attune/hot_reload/websocket.py +177 -0
  81. attune/levels.py +577 -0
  82. attune/leverage_points.py +441 -0
  83. attune/logging_config.py +261 -0
  84. attune/mcp/__init__.py +10 -0
  85. attune/mcp/server.py +506 -0
  86. attune/memory/__init__.py +237 -0
  87. attune/memory/claude_memory.py +469 -0
  88. attune/memory/config.py +224 -0
  89. attune/memory/control_panel.py +1290 -0
  90. attune/memory/control_panel_support.py +145 -0
  91. attune/memory/cross_session.py +845 -0
  92. attune/memory/edges.py +179 -0
  93. attune/memory/encryption.py +159 -0
  94. attune/memory/file_session.py +770 -0
  95. attune/memory/graph.py +570 -0
  96. attune/memory/long_term.py +913 -0
  97. attune/memory/long_term_types.py +99 -0
  98. attune/memory/mixins/__init__.py +25 -0
  99. attune/memory/mixins/backend_init_mixin.py +249 -0
  100. attune/memory/mixins/capabilities_mixin.py +208 -0
  101. attune/memory/mixins/handoff_mixin.py +208 -0
  102. attune/memory/mixins/lifecycle_mixin.py +49 -0
  103. attune/memory/mixins/long_term_mixin.py +352 -0
  104. attune/memory/mixins/promotion_mixin.py +109 -0
  105. attune/memory/mixins/short_term_mixin.py +182 -0
  106. attune/memory/nodes.py +179 -0
  107. attune/memory/redis_bootstrap.py +540 -0
  108. attune/memory/security/__init__.py +31 -0
  109. attune/memory/security/audit_logger.py +932 -0
  110. attune/memory/security/pii_scrubber.py +640 -0
  111. attune/memory/security/secrets_detector.py +678 -0
  112. attune/memory/short_term.py +2192 -0
  113. attune/memory/simple_storage.py +302 -0
  114. attune/memory/storage/__init__.py +15 -0
  115. attune/memory/storage_backend.py +167 -0
  116. attune/memory/summary_index.py +583 -0
  117. attune/memory/types.py +446 -0
  118. attune/memory/unified.py +182 -0
  119. attune/meta_workflows/__init__.py +74 -0
  120. attune/meta_workflows/agent_creator.py +248 -0
  121. attune/meta_workflows/builtin_templates.py +567 -0
  122. attune/meta_workflows/cli_commands/__init__.py +56 -0
  123. attune/meta_workflows/cli_commands/agent_commands.py +321 -0
  124. attune/meta_workflows/cli_commands/analytics_commands.py +442 -0
  125. attune/meta_workflows/cli_commands/config_commands.py +232 -0
  126. attune/meta_workflows/cli_commands/memory_commands.py +182 -0
  127. attune/meta_workflows/cli_commands/template_commands.py +354 -0
  128. attune/meta_workflows/cli_commands/workflow_commands.py +382 -0
  129. attune/meta_workflows/cli_meta_workflows.py +59 -0
  130. attune/meta_workflows/form_engine.py +292 -0
  131. attune/meta_workflows/intent_detector.py +409 -0
  132. attune/meta_workflows/models.py +569 -0
  133. attune/meta_workflows/pattern_learner.py +738 -0
  134. attune/meta_workflows/plan_generator.py +384 -0
  135. attune/meta_workflows/session_context.py +397 -0
  136. attune/meta_workflows/template_registry.py +229 -0
  137. attune/meta_workflows/workflow.py +984 -0
  138. attune/metrics/__init__.py +12 -0
  139. attune/metrics/collector.py +31 -0
  140. attune/metrics/prompt_metrics.py +194 -0
  141. attune/models/__init__.py +172 -0
  142. attune/models/__main__.py +13 -0
  143. attune/models/adaptive_routing.py +437 -0
  144. attune/models/auth_cli.py +444 -0
  145. attune/models/auth_strategy.py +450 -0
  146. attune/models/cli.py +655 -0
  147. attune/models/empathy_executor.py +354 -0
  148. attune/models/executor.py +257 -0
  149. attune/models/fallback.py +762 -0
  150. attune/models/provider_config.py +282 -0
  151. attune/models/registry.py +472 -0
  152. attune/models/tasks.py +359 -0
  153. attune/models/telemetry/__init__.py +71 -0
  154. attune/models/telemetry/analytics.py +594 -0
  155. attune/models/telemetry/backend.py +196 -0
  156. attune/models/telemetry/data_models.py +431 -0
  157. attune/models/telemetry/storage.py +489 -0
  158. attune/models/token_estimator.py +420 -0
  159. attune/models/validation.py +280 -0
  160. attune/monitoring/__init__.py +52 -0
  161. attune/monitoring/alerts.py +946 -0
  162. attune/monitoring/alerts_cli.py +448 -0
  163. attune/monitoring/multi_backend.py +271 -0
  164. attune/monitoring/otel_backend.py +362 -0
  165. attune/optimization/__init__.py +19 -0
  166. attune/optimization/context_optimizer.py +272 -0
  167. attune/orchestration/__init__.py +67 -0
  168. attune/orchestration/agent_templates.py +707 -0
  169. attune/orchestration/config_store.py +499 -0
  170. attune/orchestration/execution_strategies.py +2111 -0
  171. attune/orchestration/meta_orchestrator.py +1168 -0
  172. attune/orchestration/pattern_learner.py +696 -0
  173. attune/orchestration/real_tools.py +931 -0
  174. attune/pattern_cache.py +187 -0
  175. attune/pattern_library.py +542 -0
  176. attune/patterns/debugging/all_patterns.json +81 -0
  177. attune/patterns/debugging/workflow_20260107_1770825e.json +77 -0
  178. attune/patterns/refactoring_memory.json +89 -0
  179. attune/persistence.py +564 -0
  180. attune/platform_utils.py +265 -0
  181. attune/plugins/__init__.py +28 -0
  182. attune/plugins/base.py +361 -0
  183. attune/plugins/registry.py +268 -0
  184. attune/project_index/__init__.py +32 -0
  185. attune/project_index/cli.py +335 -0
  186. attune/project_index/index.py +667 -0
  187. attune/project_index/models.py +504 -0
  188. attune/project_index/reports.py +474 -0
  189. attune/project_index/scanner.py +777 -0
  190. attune/project_index/scanner_parallel.py +291 -0
  191. attune/prompts/__init__.py +61 -0
  192. attune/prompts/config.py +77 -0
  193. attune/prompts/context.py +177 -0
  194. attune/prompts/parser.py +285 -0
  195. attune/prompts/registry.py +313 -0
  196. attune/prompts/templates.py +208 -0
  197. attune/redis_config.py +302 -0
  198. attune/redis_memory.py +799 -0
  199. attune/resilience/__init__.py +56 -0
  200. attune/resilience/circuit_breaker.py +256 -0
  201. attune/resilience/fallback.py +179 -0
  202. attune/resilience/health.py +300 -0
  203. attune/resilience/retry.py +209 -0
  204. attune/resilience/timeout.py +135 -0
  205. attune/routing/__init__.py +43 -0
  206. attune/routing/chain_executor.py +433 -0
  207. attune/routing/classifier.py +217 -0
  208. attune/routing/smart_router.py +234 -0
  209. attune/routing/workflow_registry.py +343 -0
  210. attune/scaffolding/README.md +589 -0
  211. attune/scaffolding/__init__.py +35 -0
  212. attune/scaffolding/__main__.py +14 -0
  213. attune/scaffolding/cli.py +240 -0
  214. attune/scaffolding/templates/base_wizard.py.jinja2 +121 -0
  215. attune/scaffolding/templates/coach_wizard.py.jinja2 +321 -0
  216. attune/scaffolding/templates/domain_wizard.py.jinja2 +408 -0
  217. attune/scaffolding/templates/linear_flow_wizard.py.jinja2 +203 -0
  218. attune/socratic/__init__.py +256 -0
  219. attune/socratic/ab_testing.py +958 -0
  220. attune/socratic/blueprint.py +533 -0
  221. attune/socratic/cli.py +703 -0
  222. attune/socratic/collaboration.py +1114 -0
  223. attune/socratic/domain_templates.py +924 -0
  224. attune/socratic/embeddings.py +738 -0
  225. attune/socratic/engine.py +794 -0
  226. attune/socratic/explainer.py +682 -0
  227. attune/socratic/feedback.py +772 -0
  228. attune/socratic/forms.py +629 -0
  229. attune/socratic/generator.py +732 -0
  230. attune/socratic/llm_analyzer.py +637 -0
  231. attune/socratic/mcp_server.py +702 -0
  232. attune/socratic/session.py +312 -0
  233. attune/socratic/storage.py +667 -0
  234. attune/socratic/success.py +730 -0
  235. attune/socratic/visual_editor.py +860 -0
  236. attune/socratic/web_ui.py +958 -0
  237. attune/telemetry/__init__.py +39 -0
  238. attune/telemetry/agent_coordination.py +475 -0
  239. attune/telemetry/agent_tracking.py +367 -0
  240. attune/telemetry/approval_gates.py +545 -0
  241. attune/telemetry/cli.py +1231 -0
  242. attune/telemetry/commands/__init__.py +14 -0
  243. attune/telemetry/commands/dashboard_commands.py +696 -0
  244. attune/telemetry/event_streaming.py +409 -0
  245. attune/telemetry/feedback_loop.py +567 -0
  246. attune/telemetry/usage_tracker.py +591 -0
  247. attune/templates.py +754 -0
  248. attune/test_generator/__init__.py +38 -0
  249. attune/test_generator/__main__.py +14 -0
  250. attune/test_generator/cli.py +234 -0
  251. attune/test_generator/generator.py +355 -0
  252. attune/test_generator/risk_analyzer.py +216 -0
  253. attune/test_generator/templates/unit_test.py.jinja2 +272 -0
  254. attune/tier_recommender.py +384 -0
  255. attune/tools.py +183 -0
  256. attune/trust/__init__.py +28 -0
  257. attune/trust/circuit_breaker.py +579 -0
  258. attune/trust_building.py +527 -0
  259. attune/validation/__init__.py +19 -0
  260. attune/validation/xml_validator.py +281 -0
  261. attune/vscode_bridge.py +173 -0
  262. attune/workflow_commands.py +780 -0
  263. attune/workflow_patterns/__init__.py +33 -0
  264. attune/workflow_patterns/behavior.py +249 -0
  265. attune/workflow_patterns/core.py +76 -0
  266. attune/workflow_patterns/output.py +99 -0
  267. attune/workflow_patterns/registry.py +255 -0
  268. attune/workflow_patterns/structural.py +288 -0
  269. attune/workflows/__init__.py +539 -0
  270. attune/workflows/autonomous_test_gen.py +1268 -0
  271. attune/workflows/base.py +2667 -0
  272. attune/workflows/batch_processing.py +342 -0
  273. attune/workflows/bug_predict.py +1084 -0
  274. attune/workflows/builder.py +273 -0
  275. attune/workflows/caching.py +253 -0
  276. attune/workflows/code_review.py +1048 -0
  277. attune/workflows/code_review_adapters.py +312 -0
  278. attune/workflows/code_review_pipeline.py +722 -0
  279. attune/workflows/config.py +645 -0
  280. attune/workflows/dependency_check.py +644 -0
  281. attune/workflows/document_gen/__init__.py +25 -0
  282. attune/workflows/document_gen/config.py +30 -0
  283. attune/workflows/document_gen/report_formatter.py +162 -0
  284. attune/workflows/document_gen/workflow.py +1426 -0
  285. attune/workflows/document_manager.py +216 -0
  286. attune/workflows/document_manager_README.md +134 -0
  287. attune/workflows/documentation_orchestrator.py +1205 -0
  288. attune/workflows/history.py +510 -0
  289. attune/workflows/keyboard_shortcuts/__init__.py +39 -0
  290. attune/workflows/keyboard_shortcuts/generators.py +391 -0
  291. attune/workflows/keyboard_shortcuts/parsers.py +416 -0
  292. attune/workflows/keyboard_shortcuts/prompts.py +295 -0
  293. attune/workflows/keyboard_shortcuts/schema.py +193 -0
  294. attune/workflows/keyboard_shortcuts/workflow.py +509 -0
  295. attune/workflows/llm_base.py +363 -0
  296. attune/workflows/manage_docs.py +87 -0
  297. attune/workflows/manage_docs_README.md +134 -0
  298. attune/workflows/manage_documentation.py +821 -0
  299. attune/workflows/new_sample_workflow1.py +149 -0
  300. attune/workflows/new_sample_workflow1_README.md +150 -0
  301. attune/workflows/orchestrated_health_check.py +849 -0
  302. attune/workflows/orchestrated_release_prep.py +600 -0
  303. attune/workflows/output.py +413 -0
  304. attune/workflows/perf_audit.py +863 -0
  305. attune/workflows/pr_review.py +762 -0
  306. attune/workflows/progress.py +785 -0
  307. attune/workflows/progress_server.py +322 -0
  308. attune/workflows/progressive/README 2.md +454 -0
  309. attune/workflows/progressive/README.md +454 -0
  310. attune/workflows/progressive/__init__.py +82 -0
  311. attune/workflows/progressive/cli.py +219 -0
  312. attune/workflows/progressive/core.py +488 -0
  313. attune/workflows/progressive/orchestrator.py +723 -0
  314. attune/workflows/progressive/reports.py +520 -0
  315. attune/workflows/progressive/telemetry.py +274 -0
  316. attune/workflows/progressive/test_gen.py +495 -0
  317. attune/workflows/progressive/workflow.py +589 -0
  318. attune/workflows/refactor_plan.py +694 -0
  319. attune/workflows/release_prep.py +895 -0
  320. attune/workflows/release_prep_crew.py +969 -0
  321. attune/workflows/research_synthesis.py +404 -0
  322. attune/workflows/routing.py +168 -0
  323. attune/workflows/secure_release.py +593 -0
  324. attune/workflows/security_adapters.py +297 -0
  325. attune/workflows/security_audit.py +1329 -0
  326. attune/workflows/security_audit_phase3.py +355 -0
  327. attune/workflows/seo_optimization.py +633 -0
  328. attune/workflows/step_config.py +234 -0
  329. attune/workflows/telemetry_mixin.py +269 -0
  330. attune/workflows/test5.py +125 -0
  331. attune/workflows/test5_README.md +158 -0
  332. attune/workflows/test_coverage_boost_crew.py +849 -0
  333. attune/workflows/test_gen/__init__.py +52 -0
  334. attune/workflows/test_gen/ast_analyzer.py +249 -0
  335. attune/workflows/test_gen/config.py +88 -0
  336. attune/workflows/test_gen/data_models.py +38 -0
  337. attune/workflows/test_gen/report_formatter.py +289 -0
  338. attune/workflows/test_gen/test_templates.py +381 -0
  339. attune/workflows/test_gen/workflow.py +655 -0
  340. attune/workflows/test_gen.py +54 -0
  341. attune/workflows/test_gen_behavioral.py +477 -0
  342. attune/workflows/test_gen_parallel.py +341 -0
  343. attune/workflows/test_lifecycle.py +526 -0
  344. attune/workflows/test_maintenance.py +627 -0
  345. attune/workflows/test_maintenance_cli.py +590 -0
  346. attune/workflows/test_maintenance_crew.py +840 -0
  347. attune/workflows/test_runner.py +622 -0
  348. attune/workflows/tier_tracking.py +531 -0
  349. attune/workflows/xml_enhanced_crew.py +285 -0
  350. attune_ai-2.0.0.dist-info/METADATA +1026 -0
  351. attune_ai-2.0.0.dist-info/RECORD +457 -0
  352. attune_ai-2.0.0.dist-info/WHEEL +5 -0
  353. attune_ai-2.0.0.dist-info/entry_points.txt +26 -0
  354. attune_ai-2.0.0.dist-info/licenses/LICENSE +201 -0
  355. attune_ai-2.0.0.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +101 -0
  356. attune_ai-2.0.0.dist-info/top_level.txt +5 -0
  357. attune_healthcare/__init__.py +13 -0
  358. attune_healthcare/monitors/__init__.py +9 -0
  359. attune_healthcare/monitors/clinical_protocol_monitor.py +315 -0
  360. attune_healthcare/monitors/monitoring/__init__.py +44 -0
  361. attune_healthcare/monitors/monitoring/protocol_checker.py +300 -0
  362. attune_healthcare/monitors/monitoring/protocol_loader.py +214 -0
  363. attune_healthcare/monitors/monitoring/sensor_parsers.py +306 -0
  364. attune_healthcare/monitors/monitoring/trajectory_analyzer.py +389 -0
  365. attune_llm/README.md +553 -0
  366. attune_llm/__init__.py +28 -0
  367. attune_llm/agent_factory/__init__.py +53 -0
  368. attune_llm/agent_factory/adapters/__init__.py +85 -0
  369. attune_llm/agent_factory/adapters/autogen_adapter.py +312 -0
  370. attune_llm/agent_factory/adapters/crewai_adapter.py +483 -0
  371. attune_llm/agent_factory/adapters/haystack_adapter.py +298 -0
  372. attune_llm/agent_factory/adapters/langchain_adapter.py +362 -0
  373. attune_llm/agent_factory/adapters/langgraph_adapter.py +333 -0
  374. attune_llm/agent_factory/adapters/native.py +228 -0
  375. attune_llm/agent_factory/adapters/wizard_adapter.py +423 -0
  376. attune_llm/agent_factory/base.py +305 -0
  377. attune_llm/agent_factory/crews/__init__.py +67 -0
  378. attune_llm/agent_factory/crews/code_review.py +1113 -0
  379. attune_llm/agent_factory/crews/health_check.py +1262 -0
  380. attune_llm/agent_factory/crews/refactoring.py +1128 -0
  381. attune_llm/agent_factory/crews/security_audit.py +1018 -0
  382. attune_llm/agent_factory/decorators.py +287 -0
  383. attune_llm/agent_factory/factory.py +558 -0
  384. attune_llm/agent_factory/framework.py +193 -0
  385. attune_llm/agent_factory/memory_integration.py +328 -0
  386. attune_llm/agent_factory/resilient.py +320 -0
  387. attune_llm/agents_md/__init__.py +22 -0
  388. attune_llm/agents_md/loader.py +218 -0
  389. attune_llm/agents_md/parser.py +271 -0
  390. attune_llm/agents_md/registry.py +307 -0
  391. attune_llm/claude_memory.py +466 -0
  392. attune_llm/cli/__init__.py +8 -0
  393. attune_llm/cli/sync_claude.py +487 -0
  394. attune_llm/code_health.py +1313 -0
  395. attune_llm/commands/__init__.py +51 -0
  396. attune_llm/commands/context.py +375 -0
  397. attune_llm/commands/loader.py +301 -0
  398. attune_llm/commands/models.py +231 -0
  399. attune_llm/commands/parser.py +371 -0
  400. attune_llm/commands/registry.py +429 -0
  401. attune_llm/config/__init__.py +29 -0
  402. attune_llm/config/unified.py +291 -0
  403. attune_llm/context/__init__.py +22 -0
  404. attune_llm/context/compaction.py +455 -0
  405. attune_llm/context/manager.py +434 -0
  406. attune_llm/contextual_patterns.py +361 -0
  407. attune_llm/core.py +907 -0
  408. attune_llm/git_pattern_extractor.py +435 -0
  409. attune_llm/hooks/__init__.py +24 -0
  410. attune_llm/hooks/config.py +306 -0
  411. attune_llm/hooks/executor.py +289 -0
  412. attune_llm/hooks/registry.py +302 -0
  413. attune_llm/hooks/scripts/__init__.py +39 -0
  414. attune_llm/hooks/scripts/evaluate_session.py +201 -0
  415. attune_llm/hooks/scripts/first_time_init.py +285 -0
  416. attune_llm/hooks/scripts/pre_compact.py +207 -0
  417. attune_llm/hooks/scripts/session_end.py +183 -0
  418. attune_llm/hooks/scripts/session_start.py +163 -0
  419. attune_llm/hooks/scripts/suggest_compact.py +225 -0
  420. attune_llm/learning/__init__.py +30 -0
  421. attune_llm/learning/evaluator.py +438 -0
  422. attune_llm/learning/extractor.py +514 -0
  423. attune_llm/learning/storage.py +560 -0
  424. attune_llm/levels.py +227 -0
  425. attune_llm/pattern_confidence.py +414 -0
  426. attune_llm/pattern_resolver.py +272 -0
  427. attune_llm/pattern_summary.py +350 -0
  428. attune_llm/providers.py +967 -0
  429. attune_llm/routing/__init__.py +32 -0
  430. attune_llm/routing/model_router.py +362 -0
  431. attune_llm/security/IMPLEMENTATION_SUMMARY.md +413 -0
  432. attune_llm/security/PHASE2_COMPLETE.md +384 -0
  433. attune_llm/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
  434. attune_llm/security/QUICK_REFERENCE.md +316 -0
  435. attune_llm/security/README.md +262 -0
  436. attune_llm/security/__init__.py +62 -0
  437. attune_llm/security/audit_logger.py +929 -0
  438. attune_llm/security/audit_logger_example.py +152 -0
  439. attune_llm/security/pii_scrubber.py +640 -0
  440. attune_llm/security/secrets_detector.py +678 -0
  441. attune_llm/security/secrets_detector_example.py +304 -0
  442. attune_llm/security/secure_memdocs.py +1192 -0
  443. attune_llm/security/secure_memdocs_example.py +278 -0
  444. attune_llm/session_status.py +745 -0
  445. attune_llm/state.py +246 -0
  446. attune_llm/utils/__init__.py +5 -0
  447. attune_llm/utils/tokens.py +349 -0
  448. attune_software/SOFTWARE_PLUGIN_README.md +57 -0
  449. attune_software/__init__.py +13 -0
  450. attune_software/cli/__init__.py +120 -0
  451. attune_software/cli/inspect.py +362 -0
  452. attune_software/cli.py +574 -0
  453. attune_software/plugin.py +188 -0
  454. workflow_scaffolding/__init__.py +11 -0
  455. workflow_scaffolding/__main__.py +12 -0
  456. workflow_scaffolding/cli.py +206 -0
  457. workflow_scaffolding/generator.py +265 -0
@@ -0,0 +1,434 @@
1
+ """Context Manager for Empathy Framework
2
+
3
+ Orchestrates context compaction, state preservation, and restoration.
4
+ Integrates with the hook system to handle compaction events automatically.
5
+
6
+ Architectural patterns inspired by everything-claude-code by Affaan Mustafa.
7
+ See: https://github.com/affaan-m/everything-claude-code (MIT License)
8
+ See: ACKNOWLEDGMENTS.md for full attribution.
9
+
10
+ Copyright 2025 Smart AI Memory, LLC
11
+ Licensed under Fair Source 0.9
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import logging
17
+ from pathlib import Path
18
+ from typing import TYPE_CHECKING, Any
19
+
20
+ from attune_llm.context.compaction import (
21
+ CompactionStateManager,
22
+ CompactState,
23
+ PatternSummary,
24
+ SBARHandoff,
25
+ )
26
+
27
+ if TYPE_CHECKING:
28
+ from attune_llm.state import CollaborationState, UserPattern
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ class ContextManager:
34
+ """Manages context compaction and restoration for the Empathy Framework.
35
+
36
+ This class coordinates:
37
+ - Converting CollaborationState to CompactState for preservation
38
+ - Restoring state after context window resets
39
+ - Generating restoration prompts
40
+ - Handling SBAR handoffs for work continuity
41
+ """
42
+
43
+ def __init__(
44
+ self,
45
+ storage_dir: str | Path = ".attune/compact_states",
46
+ token_threshold: int = 50, # Percentage at which to suggest compaction
47
+ auto_save: bool = True,
48
+ ):
49
+ """Initialize the ContextManager.
50
+
51
+ Args:
52
+ storage_dir: Directory for state persistence
53
+ token_threshold: Token usage percentage to trigger compaction suggestions
54
+ auto_save: Whether to auto-save state on compaction
55
+ """
56
+ self._state_manager = CompactionStateManager(storage_dir=storage_dir)
57
+ self._token_threshold = token_threshold
58
+ self._auto_save = auto_save
59
+ self._current_session_id: str = ""
60
+ self._current_phase: str = ""
61
+ self._completed_phases: list[str] = []
62
+ self._pending_handoff: SBARHandoff | None = None
63
+
64
+ @property
65
+ def session_id(self) -> str:
66
+ """Get current session ID."""
67
+ return self._current_session_id
68
+
69
+ @session_id.setter
70
+ def session_id(self, value: str) -> None:
71
+ """Set current session ID."""
72
+ self._current_session_id = value
73
+
74
+ @property
75
+ def current_phase(self) -> str:
76
+ """Get current work phase."""
77
+ return self._current_phase
78
+
79
+ @current_phase.setter
80
+ def current_phase(self, value: str) -> None:
81
+ """Set current work phase."""
82
+ self._current_phase = value
83
+
84
+ def complete_phase(self, phase: str) -> None:
85
+ """Mark a phase as completed.
86
+
87
+ Args:
88
+ phase: Name of the completed phase
89
+ """
90
+ if phase not in self._completed_phases:
91
+ self._completed_phases.append(phase)
92
+ logger.debug(f"Completed phase: {phase}")
93
+
94
+ def set_handoff(
95
+ self,
96
+ situation: str,
97
+ background: str,
98
+ assessment: str,
99
+ recommendation: str,
100
+ priority: str = "normal",
101
+ **metadata: Any,
102
+ ) -> SBARHandoff:
103
+ """Set a pending handoff for work continuity.
104
+
105
+ Uses SBAR format for clear communication:
106
+ - Situation: What's happening now
107
+ - Background: Relevant context
108
+ - Assessment: Current understanding
109
+ - Recommendation: Suggested next action
110
+
111
+ Args:
112
+ situation: Current situation description
113
+ background: Relevant background information
114
+ assessment: Current assessment
115
+ recommendation: Recommended next action
116
+ priority: Priority level (low, normal, high, critical)
117
+ **metadata: Additional metadata
118
+
119
+ Returns:
120
+ The created SBARHandoff
121
+ """
122
+ self._pending_handoff = SBARHandoff(
123
+ situation=situation,
124
+ background=background,
125
+ assessment=assessment,
126
+ recommendation=recommendation,
127
+ priority=priority,
128
+ metadata=metadata,
129
+ )
130
+ return self._pending_handoff
131
+
132
+ def clear_handoff(self) -> None:
133
+ """Clear the pending handoff after it's been addressed."""
134
+ self._pending_handoff = None
135
+
136
+ def extract_compact_state(
137
+ self,
138
+ collaboration_state: CollaborationState,
139
+ ) -> CompactState:
140
+ """Extract CompactState from full CollaborationState.
141
+
142
+ Converts the rich collaboration state into a compact form
143
+ suitable for preservation through context resets.
144
+
145
+ Args:
146
+ collaboration_state: Full collaboration state
147
+
148
+ Returns:
149
+ Compact state for preservation
150
+ """
151
+ # Convert patterns to summaries
152
+ pattern_summaries = [
153
+ self._pattern_to_summary(p)
154
+ for p in collaboration_state.detected_patterns[:10] # Top 10
155
+ ]
156
+
157
+ # Extract key preferences (limit to essentials)
158
+ key_preferences = self._extract_key_preferences(collaboration_state.preferences)
159
+
160
+ return CompactState(
161
+ user_id=collaboration_state.user_id,
162
+ trust_level=collaboration_state.trust_level,
163
+ empathy_level=collaboration_state.current_level,
164
+ detected_patterns=pattern_summaries,
165
+ session_id=self._current_session_id,
166
+ current_phase=self._current_phase,
167
+ completed_phases=list(self._completed_phases),
168
+ pending_handoff=self._pending_handoff,
169
+ interaction_count=len(collaboration_state.interactions),
170
+ successful_actions=collaboration_state.successful_actions,
171
+ failed_actions=collaboration_state.failed_actions,
172
+ preferences=key_preferences,
173
+ )
174
+
175
+ def _pattern_to_summary(self, pattern: UserPattern) -> PatternSummary:
176
+ """Convert UserPattern to PatternSummary.
177
+
178
+ Args:
179
+ pattern: Full pattern object
180
+
181
+ Returns:
182
+ Compact pattern summary
183
+ """
184
+ return PatternSummary(
185
+ pattern_type=pattern.pattern_type.value,
186
+ trigger=pattern.trigger,
187
+ action=pattern.action,
188
+ confidence=pattern.confidence,
189
+ occurrences=pattern.occurrences,
190
+ )
191
+
192
+ def _extract_key_preferences(
193
+ self,
194
+ preferences: dict[str, Any],
195
+ max_items: int = 10,
196
+ ) -> dict[str, Any]:
197
+ """Extract key preferences for compaction.
198
+
199
+ Filters and limits preferences to essential items.
200
+
201
+ Args:
202
+ preferences: Full preferences dict
203
+ max_items: Maximum items to include
204
+
205
+ Returns:
206
+ Filtered preferences dict
207
+ """
208
+ # Priority keys to always include if present
209
+ priority_keys = {
210
+ "response_style",
211
+ "code_style",
212
+ "verbosity",
213
+ "confirmation_level",
214
+ "tool_usage",
215
+ "language",
216
+ "timezone",
217
+ }
218
+
219
+ result: dict[str, Any] = {}
220
+
221
+ # Add priority keys first
222
+ for key in priority_keys:
223
+ if key in preferences:
224
+ result[key] = preferences[key]
225
+ if len(result) >= max_items:
226
+ return result
227
+
228
+ # Add remaining keys up to limit
229
+ for key, value in preferences.items():
230
+ if key not in result:
231
+ # Skip complex nested structures
232
+ if isinstance(value, (str, int, float, bool)):
233
+ result[key] = value
234
+ elif isinstance(value, list) and len(value) <= 5:
235
+ result[key] = value
236
+
237
+ if len(result) >= max_items:
238
+ break
239
+
240
+ return result
241
+
242
+ def save_for_compaction(
243
+ self,
244
+ collaboration_state: CollaborationState,
245
+ ) -> Path:
246
+ """Save state for upcoming compaction.
247
+
248
+ Called before context compaction to preserve state.
249
+
250
+ Args:
251
+ collaboration_state: Current collaboration state
252
+
253
+ Returns:
254
+ Path to saved state file
255
+ """
256
+ compact_state = self.extract_compact_state(collaboration_state)
257
+ return self._state_manager.save_state(compact_state)
258
+
259
+ def restore_state(self, user_id: str) -> CompactState | None:
260
+ """Restore the most recent state for a user.
261
+
262
+ Args:
263
+ user_id: User identifier
264
+
265
+ Returns:
266
+ Most recent CompactState or None
267
+ """
268
+ state = self._state_manager.load_latest_state(user_id)
269
+
270
+ if state:
271
+ # Restore session tracking
272
+ self._current_session_id = state.session_id
273
+ self._current_phase = state.current_phase
274
+ self._completed_phases = list(state.completed_phases)
275
+ self._pending_handoff = state.pending_handoff
276
+
277
+ logger.info(f"Restored state for user {user_id}")
278
+
279
+ return state
280
+
281
+ def restore_by_session(self, session_id: str) -> CompactState | None:
282
+ """Restore state for a specific session.
283
+
284
+ Args:
285
+ session_id: Session identifier
286
+
287
+ Returns:
288
+ CompactState for session or None
289
+ """
290
+ state = self._state_manager.load_state_by_session(session_id)
291
+
292
+ if state:
293
+ self._current_session_id = state.session_id
294
+ self._current_phase = state.current_phase
295
+ self._completed_phases = list(state.completed_phases)
296
+ self._pending_handoff = state.pending_handoff
297
+
298
+ logger.info(f"Restored state for session {session_id}")
299
+
300
+ return state
301
+
302
+ def generate_restoration_prompt(self, user_id: str) -> str | None:
303
+ """Generate a restoration prompt for session continuity.
304
+
305
+ Loads the most recent state and formats it as a prompt
306
+ that can be injected at session start.
307
+
308
+ Args:
309
+ user_id: User identifier
310
+
311
+ Returns:
312
+ Formatted restoration prompt or None if no state
313
+ """
314
+ state = self.restore_state(user_id)
315
+
316
+ if not state:
317
+ return None
318
+
319
+ return state.format_restoration_prompt()
320
+
321
+ def should_suggest_compaction(
322
+ self,
323
+ token_usage_percent: float,
324
+ message_count: int | None = None,
325
+ ) -> bool:
326
+ """Determine if compaction should be suggested.
327
+
328
+ Args:
329
+ token_usage_percent: Current token usage as percentage (0-100)
330
+ message_count: Optional message count for additional heuristic
331
+
332
+ Returns:
333
+ True if compaction should be suggested
334
+ """
335
+ # Primary check: token usage
336
+ if token_usage_percent >= self._token_threshold:
337
+ return True
338
+
339
+ # Secondary check: message count (if provided)
340
+ if message_count and message_count >= 50:
341
+ return True
342
+
343
+ return False
344
+
345
+ def get_compaction_message(
346
+ self,
347
+ token_usage_percent: float,
348
+ ) -> str:
349
+ """Generate a compaction suggestion message.
350
+
351
+ Args:
352
+ token_usage_percent: Current token usage percentage
353
+
354
+ Returns:
355
+ Formatted suggestion message
356
+ """
357
+ return (
358
+ f"Context usage at {token_usage_percent:.0f}%. "
359
+ "Consider running `/compact` to preserve state and free context space. "
360
+ "Your collaboration state, trust level, and detected patterns will be preserved."
361
+ )
362
+
363
+ def apply_state_to_collaboration(
364
+ self,
365
+ compact_state: CompactState,
366
+ collaboration_state: CollaborationState,
367
+ ) -> None:
368
+ """Apply restored CompactState to CollaborationState.
369
+
370
+ Updates a CollaborationState with values from a restored CompactState.
371
+
372
+ Args:
373
+ compact_state: State to restore from
374
+ collaboration_state: State to update
375
+ """
376
+ # Restore trust level
377
+ collaboration_state.trust_level = compact_state.trust_level
378
+
379
+ # Restore empathy level
380
+ collaboration_state.current_level = compact_state.empathy_level
381
+
382
+ # Restore counters
383
+ collaboration_state.successful_actions = compact_state.successful_actions
384
+ collaboration_state.failed_actions = compact_state.failed_actions
385
+
386
+ # Restore preferences
387
+ collaboration_state.preferences.update(compact_state.preferences)
388
+
389
+ # Note: Patterns and interactions are not restored from compact state
390
+ # as the full state would be needed for those
391
+
392
+ logger.info(
393
+ f"Applied compact state to collaboration: "
394
+ f"trust={compact_state.trust_level:.2f}, "
395
+ f"level={compact_state.empathy_level}"
396
+ )
397
+
398
+ def get_state_summary(self, user_id: str) -> dict[str, Any] | None:
399
+ """Get a summary of saved states for a user.
400
+
401
+ Args:
402
+ user_id: User identifier
403
+
404
+ Returns:
405
+ Summary dict or None if no states
406
+ """
407
+ states = self._state_manager.get_all_states(user_id)
408
+
409
+ if not states:
410
+ return None
411
+
412
+ latest = states[0]
413
+
414
+ return {
415
+ "user_id": user_id,
416
+ "states_count": len(states),
417
+ "latest_saved": latest.saved_at,
418
+ "latest_trust_level": latest.trust_level,
419
+ "latest_empathy_level": latest.empathy_level,
420
+ "latest_session_id": latest.session_id,
421
+ "patterns_count": len(latest.detected_patterns),
422
+ "has_pending_handoff": latest.pending_handoff is not None,
423
+ }
424
+
425
+ def clear_states(self, user_id: str) -> int:
426
+ """Clear all saved states for a user.
427
+
428
+ Args:
429
+ user_id: User identifier
430
+
431
+ Returns:
432
+ Number of states cleared
433
+ """
434
+ return self._state_manager.clear_user_states(user_id)