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,99 @@
1
+ """Type definitions for long-term memory system
2
+
3
+ This module contains data classes, enums, and exceptions used by the long-term
4
+ memory system. Extracted from long_term.py for better modularity and testability.
5
+
6
+ Key Types:
7
+ - Classification: Three-tier security classification system
8
+ - ClassificationRules: Security rules per classification level
9
+ - PatternMetadata: Metadata for stored patterns
10
+ - SecurePattern: Pattern with content and metadata
11
+ - SecurityError, PermissionError: Exception types
12
+
13
+ Copyright 2025 Smart AI Memory, LLC
14
+ Licensed under Fair Source 0.9
15
+ """
16
+
17
+ from dataclasses import dataclass, field
18
+ from enum import Enum
19
+ from typing import Any
20
+
21
+
22
+ class Classification(Enum):
23
+ """Three-tier classification system for MemDocs patterns"""
24
+
25
+ PUBLIC = "PUBLIC" # Shareable across organization, anonymized
26
+ INTERNAL = "INTERNAL" # Team/project only, no PII or secrets
27
+ SENSITIVE = "SENSITIVE" # Encrypted at rest, access-controlled (HIPAA, finance)
28
+
29
+
30
+ @dataclass
31
+ class ClassificationRules:
32
+ """Security rules for each classification level"""
33
+
34
+ classification: Classification
35
+ encryption_required: bool
36
+ retention_days: int
37
+ access_level: str # "all_users", "project_team", "explicit_permission"
38
+ audit_all_access: bool = False
39
+
40
+
41
+ # Default classification rules based on enterprise security policy
42
+ DEFAULT_CLASSIFICATION_RULES: dict[Classification, ClassificationRules] = {
43
+ Classification.PUBLIC: ClassificationRules(
44
+ classification=Classification.PUBLIC,
45
+ encryption_required=False,
46
+ retention_days=365,
47
+ access_level="all_users",
48
+ audit_all_access=False,
49
+ ),
50
+ Classification.INTERNAL: ClassificationRules(
51
+ classification=Classification.INTERNAL,
52
+ encryption_required=False,
53
+ retention_days=180,
54
+ access_level="project_team",
55
+ audit_all_access=False,
56
+ ),
57
+ Classification.SENSITIVE: ClassificationRules(
58
+ classification=Classification.SENSITIVE,
59
+ encryption_required=True,
60
+ retention_days=90,
61
+ access_level="explicit_permission",
62
+ audit_all_access=True,
63
+ ),
64
+ }
65
+
66
+
67
+ @dataclass
68
+ class PatternMetadata:
69
+ """Metadata for stored MemDocs patterns"""
70
+
71
+ pattern_id: str
72
+ created_by: str
73
+ created_at: str
74
+ classification: str
75
+ retention_days: int
76
+ encrypted: bool
77
+ pattern_type: str
78
+ sanitization_applied: bool
79
+ pii_removed: int
80
+ secrets_detected: int
81
+ access_control: dict[str, Any] = field(default_factory=dict)
82
+ custom_metadata: dict[str, Any] = field(default_factory=dict)
83
+
84
+
85
+ @dataclass
86
+ class SecurePattern:
87
+ """Represents a securely stored pattern"""
88
+
89
+ pattern_id: str
90
+ content: str
91
+ metadata: PatternMetadata
92
+
93
+
94
+ class SecurityError(Exception):
95
+ """Raised when security policy is violated"""
96
+
97
+
98
+ class PermissionError(Exception):
99
+ """Raised when access is denied"""
@@ -0,0 +1,25 @@
1
+ """Memory mixins for UnifiedMemory composition.
2
+
3
+ Provides modular capabilities through mixin composition pattern.
4
+
5
+ Copyright 2025 Smart AI Memory, LLC
6
+ Licensed under Fair Source 0.9
7
+ """
8
+
9
+ from .backend_init_mixin import BackendInitMixin
10
+ from .capabilities_mixin import CapabilitiesMixin
11
+ from .handoff_mixin import HandoffAndExportMixin
12
+ from .lifecycle_mixin import LifecycleMixin
13
+ from .long_term_mixin import LongTermOperationsMixin
14
+ from .promotion_mixin import PatternPromotionMixin
15
+ from .short_term_mixin import ShortTermOperationsMixin
16
+
17
+ __all__ = [
18
+ "BackendInitMixin",
19
+ "CapabilitiesMixin",
20
+ "HandoffAndExportMixin",
21
+ "LifecycleMixin",
22
+ "LongTermOperationsMixin",
23
+ "PatternPromotionMixin",
24
+ "ShortTermOperationsMixin",
25
+ ]
@@ -0,0 +1,249 @@
1
+ """Backend initialization mixin for UnifiedMemory.
2
+
3
+ Handles initialization of file session, Redis, and long-term memory backends.
4
+
5
+ Copyright 2025 Smart AI Memory, LLC
6
+ Licensed under Fair Source 0.9
7
+ """
8
+
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ import structlog
12
+
13
+ if TYPE_CHECKING:
14
+ from ..file_session import FileSessionMemory
15
+ from ..long_term import LongTermMemory, SecureMemDocsIntegration
16
+ from ..redis_bootstrap import RedisStatus
17
+ from ..short_term import RedisShortTermMemory
18
+
19
+ logger = structlog.get_logger(__name__)
20
+
21
+
22
+ class BackendInitMixin:
23
+ """Mixin providing backend initialization for UnifiedMemory."""
24
+
25
+ # Type hints for attributes that will be provided by UnifiedMemory
26
+ user_id: str
27
+ config: Any # MemoryConfig
28
+ _file_session: "FileSessionMemory | None"
29
+ _short_term: "RedisShortTermMemory | None"
30
+ _long_term: "SecureMemDocsIntegration | None"
31
+ _simple_long_term: "LongTermMemory | None"
32
+ _redis_status: "RedisStatus | None"
33
+ _initialized: bool
34
+
35
+ # =========================================================================
36
+ # BACKEND INITIALIZATION
37
+ # =========================================================================
38
+
39
+ def _initialize_backends(self):
40
+ """Initialize short-term and long-term memory backends.
41
+
42
+ File-First Architecture:
43
+ 1. FileSessionMemory is always initialized (primary storage)
44
+ 2. Redis is optional (for real-time features like pub/sub)
45
+ 3. Falls back gracefully when Redis is unavailable
46
+ """
47
+ from ..claude_memory import ClaudeMemoryConfig
48
+ from ..config import get_redis_memory
49
+ from ..file_session import FileSessionConfig, FileSessionMemory
50
+ from ..long_term import LongTermMemory, SecureMemDocsIntegration
51
+ from ..redis_bootstrap import RedisStartMethod, RedisStatus, ensure_redis
52
+ from ..short_term import RedisShortTermMemory
53
+
54
+ if self._initialized:
55
+ return
56
+
57
+ # Initialize file-based session memory (PRIMARY - always available)
58
+ if self.config.file_session_enabled:
59
+ try:
60
+ file_config = FileSessionConfig(base_dir=self.config.file_session_dir)
61
+ self._file_session = FileSessionMemory(
62
+ user_id=self.user_id,
63
+ config=file_config,
64
+ )
65
+ logger.info(
66
+ "file_session_memory_initialized",
67
+ base_dir=self.config.file_session_dir,
68
+ session_id=self._file_session._state.session_id,
69
+ )
70
+ except Exception as e:
71
+ logger.error("file_session_memory_failed", error=str(e))
72
+ self._file_session = None
73
+
74
+ # Initialize Redis short-term memory (OPTIONAL - for real-time features)
75
+ try:
76
+ if self.config.redis_mock:
77
+ self._short_term = RedisShortTermMemory(use_mock=True)
78
+ self._redis_status = RedisStatus(
79
+ available=False,
80
+ method=RedisStartMethod.MOCK,
81
+ message="Mock mode explicitly enabled",
82
+ )
83
+ elif self.config.redis_url:
84
+ self._short_term = get_redis_memory(url=self.config.redis_url)
85
+ self._redis_status = RedisStatus(
86
+ available=True,
87
+ method=RedisStartMethod.ALREADY_RUNNING,
88
+ message="Connected via REDIS_URL",
89
+ )
90
+ # Use auto-start if enabled
91
+ elif self.config.redis_auto_start:
92
+ self._redis_status = ensure_redis(
93
+ host=self.config.redis_host,
94
+ port=self.config.redis_port,
95
+ auto_start=True,
96
+ verbose=True,
97
+ )
98
+ if self._redis_status.available:
99
+ self._short_term = RedisShortTermMemory(
100
+ host=self.config.redis_host,
101
+ port=self.config.redis_port,
102
+ use_mock=False,
103
+ )
104
+ else:
105
+ # File session is primary, so Redis mock is not needed
106
+ self._short_term = None
107
+ self._redis_status = RedisStatus(
108
+ available=False,
109
+ method=RedisStartMethod.MOCK,
110
+ message="Redis unavailable, using file-based storage",
111
+ )
112
+ else:
113
+ # Try to connect to existing Redis
114
+ try:
115
+ self._short_term = get_redis_memory()
116
+ if self._short_term.is_connected():
117
+ self._redis_status = RedisStatus(
118
+ available=True,
119
+ method=RedisStartMethod.ALREADY_RUNNING,
120
+ message="Connected to existing Redis",
121
+ )
122
+ else:
123
+ self._short_term = None
124
+ self._redis_status = RedisStatus(
125
+ available=False,
126
+ method=RedisStartMethod.MOCK,
127
+ message="Redis not available, using file-based storage",
128
+ )
129
+ except Exception:
130
+ self._short_term = None
131
+ self._redis_status = RedisStatus(
132
+ available=False,
133
+ method=RedisStartMethod.MOCK,
134
+ message="Redis not available, using file-based storage",
135
+ )
136
+
137
+ logger.info(
138
+ "short_term_memory_initialized",
139
+ redis_available=self._redis_status.available if self._redis_status else False,
140
+ file_session_available=self._file_session is not None,
141
+ redis_method=self._redis_status.method.value if self._redis_status else "none",
142
+ environment=self.config.environment.value,
143
+ )
144
+
145
+ # Fail if Redis is required but not available
146
+ if self.config.redis_required and not (
147
+ self._redis_status and self._redis_status.available
148
+ ):
149
+ raise RuntimeError(
150
+ "Redis is required but not available. "
151
+ f"Config requires Redis (redis_required=True, environment={self.config.environment.value}). "
152
+ "Either: (1) Start Redis server, (2) Set REDIS_URL environment variable, "
153
+ "or (3) Set redis_required=False in MemoryConfig."
154
+ )
155
+
156
+ except RuntimeError:
157
+ raise # Re-raise required Redis error
158
+ except Exception as e:
159
+ logger.warning("redis_initialization_failed", error=str(e))
160
+ self._short_term = None
161
+ self._redis_status = RedisStatus(
162
+ available=False,
163
+ method=RedisStartMethod.MOCK,
164
+ message=f"Failed to initialize: {e}",
165
+ )
166
+
167
+ # Initialize long-term memory (SecureMemDocs)
168
+ try:
169
+ claude_config = ClaudeMemoryConfig(
170
+ enabled=self.config.claude_memory_enabled,
171
+ load_enterprise=self.config.load_enterprise_memory,
172
+ load_project=self.config.load_project_memory,
173
+ load_user=self.config.load_user_memory,
174
+ )
175
+ self._long_term = SecureMemDocsIntegration(
176
+ claude_memory_config=claude_config,
177
+ storage_dir=self.config.storage_dir,
178
+ enable_encryption=self.config.encryption_enabled,
179
+ )
180
+
181
+ logger.info(
182
+ "long_term_memory_initialized",
183
+ storage_dir=self.config.storage_dir,
184
+ encryption=self.config.encryption_enabled,
185
+ )
186
+ except Exception as e:
187
+ logger.error("long_term_memory_failed", error=str(e))
188
+ self._long_term = None
189
+
190
+ # Initialize simple long-term memory (for testing and simple use cases)
191
+ try:
192
+ self._simple_long_term = LongTermMemory(storage_path=self.config.storage_dir)
193
+ logger.debug("simple_long_term_memory_initialized")
194
+ except Exception as e:
195
+ logger.error("simple_long_term_memory_failed", error=str(e))
196
+ self._simple_long_term = None
197
+
198
+ self._initialized = True
199
+
200
+ def get_backend_status(self) -> dict[str, Any]:
201
+ """Get the current status of all memory backends.
202
+
203
+ Returns a structured dict suitable for health checks, debugging,
204
+ and dashboard display. Can be serialized to JSON.
205
+
206
+ Returns:
207
+ dict with keys:
208
+ - environment: Current environment (development/staging/production)
209
+ - short_term: Status of Redis-based short-term memory
210
+ - long_term: Status of persistent long-term memory
211
+ - initialized: Whether backends have been initialized
212
+
213
+ Example:
214
+ >>> memory = UnifiedMemory(user_id="agent")
215
+ >>> status = memory.get_backend_status()
216
+ >>> print(status["short_term"]["available"])
217
+ True
218
+
219
+ """
220
+ from ..redis_bootstrap import RedisStartMethod
221
+
222
+ short_term_status: dict[str, Any] = {
223
+ "available": False,
224
+ "mock": True,
225
+ "method": "unknown",
226
+ "message": "Not initialized",
227
+ }
228
+
229
+ if self._redis_status:
230
+ short_term_status = {
231
+ "available": self._redis_status.available,
232
+ "mock": not self._redis_status.available
233
+ or self._redis_status.method == RedisStartMethod.MOCK,
234
+ "method": self._redis_status.method.value,
235
+ "message": self._redis_status.message,
236
+ }
237
+
238
+ long_term_status: dict[str, Any] = {
239
+ "available": self._long_term is not None,
240
+ "storage_dir": self.config.storage_dir,
241
+ "encryption_enabled": self.config.encryption_enabled,
242
+ }
243
+
244
+ return {
245
+ "environment": self.config.environment.value,
246
+ "initialized": self._initialized,
247
+ "short_term": short_term_status,
248
+ "long_term": long_term_status,
249
+ }
@@ -0,0 +1,208 @@
1
+ """Capabilities and health check mixin for UnifiedMemory.
2
+
3
+ Provides backend availability checks, health monitoring, and feature detection.
4
+
5
+ Copyright 2025 Smart AI Memory, LLC
6
+ Licensed under Fair Source 0.9
7
+ """
8
+
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ if TYPE_CHECKING:
12
+ from ..file_session import FileSessionMemory
13
+ from ..long_term import LongTermMemory
14
+ from ..redis_bootstrap import RedisStatus
15
+ from ..short_term import RedisShortTermMemory
16
+
17
+
18
+ class CapabilitiesMixin:
19
+ """Mixin providing capability detection and health checks for UnifiedMemory."""
20
+
21
+ # Type hints for attributes that will be provided by UnifiedMemory
22
+ _file_session: "FileSessionMemory | None"
23
+ _short_term: "RedisShortTermMemory | None"
24
+ _long_term: Any # SecureMemDocsIntegration
25
+ _simple_long_term: "LongTermMemory | None"
26
+ _redis_status: "RedisStatus | None"
27
+ config: Any # MemoryConfig
28
+
29
+ # =========================================================================
30
+ # BACKEND AVAILABILITY CHECKS
31
+ # =========================================================================
32
+
33
+ @property
34
+ def has_short_term(self) -> bool:
35
+ """Check if short-term memory is available."""
36
+ return self._short_term is not None
37
+
38
+ @property
39
+ def has_long_term(self) -> bool:
40
+ """Check if long-term memory is available."""
41
+ return self._long_term is not None
42
+
43
+ @property
44
+ def redis_status(self) -> "RedisStatus | None":
45
+ """Get Redis connection status."""
46
+ return self._redis_status
47
+
48
+ @property
49
+ def using_real_redis(self) -> bool:
50
+ """Check if using real Redis (not mock)."""
51
+ from ..redis_bootstrap import RedisStartMethod
52
+
53
+ return (
54
+ self._redis_status is not None
55
+ and self._redis_status.available
56
+ and self._redis_status.method != RedisStartMethod.MOCK
57
+ )
58
+
59
+ @property
60
+ def short_term(self) -> "RedisShortTermMemory":
61
+ """Get short-term memory backend for direct access (testing).
62
+
63
+ Returns:
64
+ RedisShortTermMemory instance
65
+
66
+ Raises:
67
+ RuntimeError: If short-term memory is not initialized
68
+
69
+ """
70
+ if self._short_term is None:
71
+ raise RuntimeError(
72
+ "Short-term memory not initialized. "
73
+ "Ensure Redis is running and UnifiedMemory was initialized with Redis enabled."
74
+ )
75
+ return self._short_term
76
+
77
+ @property
78
+ def long_term(self) -> "LongTermMemory":
79
+ """Get simple long-term memory backend for direct access (testing).
80
+
81
+ Returns:
82
+ LongTermMemory instance
83
+
84
+ Raises:
85
+ RuntimeError: If long-term memory is not initialized
86
+
87
+ Note:
88
+ For production use with security features (PII scrubbing, encryption),
89
+ use persist_pattern() and recall_pattern() methods instead.
90
+
91
+ """
92
+ if self._simple_long_term is None:
93
+ raise RuntimeError(
94
+ "Long-term memory not initialized. "
95
+ "Ensure UnifiedMemory was initialized with long_term_enabled=True."
96
+ )
97
+ return self._simple_long_term
98
+
99
+ # =========================================================================
100
+ # HEALTH CHECKS
101
+ # =========================================================================
102
+
103
+ def health_check(self) -> dict[str, Any]:
104
+ """Check health of memory backends.
105
+
106
+ Returns:
107
+ Status of each memory backend
108
+
109
+ """
110
+ redis_info: dict[str, Any] = {
111
+ "available": self.has_short_term,
112
+ "mock_mode": not self.using_real_redis,
113
+ }
114
+ if self._redis_status:
115
+ redis_info["method"] = self._redis_status.method.value
116
+ redis_info["host"] = self._redis_status.host
117
+ redis_info["port"] = self._redis_status.port
118
+
119
+ return {
120
+ "file_session": {
121
+ "available": self._file_session is not None,
122
+ "session_id": self._file_session._state.session_id if self._file_session else None,
123
+ "base_dir": self.config.file_session_dir,
124
+ },
125
+ "short_term": redis_info,
126
+ "long_term": {
127
+ "available": self.has_long_term,
128
+ "storage_dir": self.config.storage_dir,
129
+ "encryption": self.config.encryption_enabled,
130
+ },
131
+ "environment": self.config.environment.value,
132
+ }
133
+
134
+ # =========================================================================
135
+ # CAPABILITY DETECTION (File-First Architecture)
136
+ # =========================================================================
137
+
138
+ @property
139
+ def has_file_session(self) -> bool:
140
+ """Check if file-based session memory is available (always True if enabled)."""
141
+ return self._file_session is not None
142
+
143
+ @property
144
+ def file_session(self) -> "FileSessionMemory":
145
+ """Get file session memory backend for direct access.
146
+
147
+ Returns:
148
+ FileSessionMemory instance
149
+
150
+ Raises:
151
+ RuntimeError: If file session memory is not initialized
152
+ """
153
+ if self._file_session is None:
154
+ raise RuntimeError(
155
+ "File session memory not initialized. "
156
+ "File session tracking is automatically enabled when UnifiedMemory is initialized."
157
+ )
158
+ return self._file_session
159
+
160
+ def supports_realtime(self) -> bool:
161
+ """Check if real-time features are available (requires Redis).
162
+
163
+ Real-time features include:
164
+ - Pub/Sub messaging between agents
165
+ - Cross-session coordination
166
+ - Distributed task queues
167
+
168
+ Returns:
169
+ True if Redis is available and connected
170
+ """
171
+ return self.using_real_redis
172
+
173
+ def supports_distributed(self) -> bool:
174
+ """Check if distributed features are available (requires Redis).
175
+
176
+ Distributed features include:
177
+ - Multi-process coordination
178
+ - Cross-session state sharing
179
+ - Agent discovery
180
+
181
+ Returns:
182
+ True if Redis is available and connected
183
+ """
184
+ return self.using_real_redis
185
+
186
+ def supports_persistence(self) -> bool:
187
+ """Check if persistence is available (always True with file-first).
188
+
189
+ Returns:
190
+ True if file session or long-term memory is available
191
+ """
192
+ return self._file_session is not None or self._long_term is not None
193
+
194
+ def get_capabilities(self) -> dict[str, bool]:
195
+ """Get a summary of available memory capabilities.
196
+
197
+ Returns:
198
+ Dictionary mapping capability names to availability
199
+ """
200
+ return {
201
+ "file_session": self.has_file_session,
202
+ "redis": self.using_real_redis,
203
+ "long_term": self.has_long_term,
204
+ "persistence": self.supports_persistence(),
205
+ "realtime": self.supports_realtime(),
206
+ "distributed": self.supports_distributed(),
207
+ "encryption": self.config.encryption_enabled and self.has_long_term,
208
+ }