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,109 @@
1
+ """Pattern promotion mixin for UnifiedMemory.
2
+
3
+ Handles promotion of patterns from short-term to long-term memory.
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 ..long_term import Classification
15
+ from ..short_term import AgentCredentials, RedisShortTermMemory
16
+
17
+ logger = structlog.get_logger(__name__)
18
+
19
+
20
+ class PatternPromotionMixin:
21
+ """Mixin providing pattern promotion capabilities for UnifiedMemory."""
22
+
23
+ # Type hints for attributes that will be provided by UnifiedMemory
24
+ _short_term: "RedisShortTermMemory | None"
25
+ _long_term: Any # SecureMemDocsIntegration | None
26
+
27
+ # Needs access to methods from other mixins
28
+ @property
29
+ def credentials(self) -> "AgentCredentials":
30
+ """Get credentials - provided by ShortTermOperationsMixin."""
31
+ ...
32
+
33
+ def get_staged_patterns(self) -> list[dict]:
34
+ """Get staged patterns - provided by ShortTermOperationsMixin."""
35
+ ...
36
+
37
+ def persist_pattern(
38
+ self,
39
+ content: str,
40
+ pattern_type: str,
41
+ classification: "Classification | str | None" = None,
42
+ auto_classify: bool = True,
43
+ metadata: dict[str, Any] | None = None,
44
+ ) -> dict[str, Any] | None:
45
+ """Persist pattern - provided by LongTermOperationsMixin."""
46
+ ...
47
+
48
+ # =========================================================================
49
+ # PATTERN PROMOTION (SHORT-TERM → LONG-TERM)
50
+ # =========================================================================
51
+
52
+ def promote_pattern(
53
+ self,
54
+ staged_pattern_id: str,
55
+ classification: "Classification | str | None" = None,
56
+ auto_classify: bool = True,
57
+ ) -> dict[str, Any] | None:
58
+ """Promote a staged pattern from short-term to long-term memory.
59
+
60
+ Args:
61
+ staged_pattern_id: ID of staged pattern to promote
62
+ classification: Override classification (or auto-detect)
63
+ auto_classify: Auto-detect classification from content
64
+
65
+ Returns:
66
+ Long-term storage result, or None if failed
67
+
68
+ """
69
+ if not self._short_term or not self._long_term:
70
+ logger.error("memory_backends_unavailable")
71
+ return None
72
+
73
+ # Retrieve staged pattern
74
+ staged_patterns = self.get_staged_patterns()
75
+ staged = next(
76
+ (p for p in staged_patterns if p.get("pattern_id") == staged_pattern_id),
77
+ None,
78
+ )
79
+
80
+ if not staged:
81
+ logger.warning("staged_pattern_not_found", pattern_id=staged_pattern_id)
82
+ return None
83
+
84
+ # Persist to long-term storage
85
+ # Content is stored in context dict by stage_pattern
86
+ context = staged.get("context", {})
87
+ content = context.get("content", "") or staged.get("description", "")
88
+ result = self.persist_pattern(
89
+ content=content,
90
+ pattern_type=staged.get("pattern_type", "general"),
91
+ classification=classification,
92
+ auto_classify=auto_classify,
93
+ metadata=context,
94
+ )
95
+
96
+ if result:
97
+ # Remove from staging (use promote_pattern which handles deletion)
98
+ try:
99
+ self._short_term.promote_pattern(staged_pattern_id, self.credentials)
100
+ except PermissionError:
101
+ # If we can't promote (delete from staging), just log it
102
+ logger.warning("could_not_remove_from_staging", pattern_id=staged_pattern_id)
103
+ logger.info(
104
+ "pattern_promoted",
105
+ staged_id=staged_pattern_id,
106
+ long_term_id=result.get("pattern_id"),
107
+ )
108
+
109
+ return result
@@ -0,0 +1,182 @@
1
+ """Short-term memory operations mixin for UnifiedMemory.
2
+
3
+ Provides working memory operations (stash/retrieve) and pattern staging.
4
+
5
+ Copyright 2025 Smart AI Memory, LLC
6
+ Licensed under Fair Source 0.9
7
+ """
8
+
9
+ import uuid
10
+ from datetime import datetime
11
+ from typing import TYPE_CHECKING, Any
12
+
13
+ import structlog
14
+
15
+ if TYPE_CHECKING:
16
+ from ..file_session import FileSessionMemory
17
+ from ..redis_bootstrap import RedisStatus
18
+ from ..short_term import (
19
+ AccessTier,
20
+ AgentCredentials,
21
+ RedisShortTermMemory,
22
+ )
23
+
24
+ logger = structlog.get_logger(__name__)
25
+
26
+
27
+ class ShortTermOperationsMixin:
28
+ """Mixin providing short-term memory operations for UnifiedMemory."""
29
+
30
+ # Type hints for attributes that will be provided by UnifiedMemory
31
+ user_id: str
32
+ access_tier: "AccessTier"
33
+ _file_session: "FileSessionMemory | None"
34
+ _short_term: "RedisShortTermMemory | None"
35
+ _redis_status: "RedisStatus | None"
36
+ config: Any # MemoryConfig
37
+
38
+ @property
39
+ def credentials(self) -> "AgentCredentials":
40
+ """Get agent credentials for short-term memory operations."""
41
+ from ..short_term import AgentCredentials
42
+
43
+ return AgentCredentials(agent_id=self.user_id, tier=self.access_tier)
44
+
45
+ # =========================================================================
46
+ # SHORT-TERM MEMORY OPERATIONS (Working Memory)
47
+ # =========================================================================
48
+
49
+ def stash(self, key: str, value: Any, ttl_seconds: int | None = None) -> bool:
50
+ """Store data in working memory with TTL.
51
+
52
+ Uses file-based session as primary storage, with optional Redis for
53
+ real-time features. Data is persisted to disk automatically.
54
+
55
+ Args:
56
+ key: Storage key
57
+ value: Data to store (must be JSON-serializable)
58
+ ttl_seconds: Time-to-live in seconds (default from config)
59
+
60
+ Returns:
61
+ True if stored successfully
62
+
63
+ """
64
+ from ..short_term import TTLStrategy
65
+
66
+ ttl = ttl_seconds or self.config.default_ttl_seconds
67
+
68
+ # Primary: File session memory (always available)
69
+ if self._file_session:
70
+ self._file_session.stash(key, value, ttl=ttl)
71
+
72
+ # Optional: Redis for real-time sync
73
+ if self._short_term and self._redis_status and self._redis_status.available:
74
+ # Map ttl_seconds to TTLStrategy
75
+ ttl_strategy = TTLStrategy.WORKING_RESULTS
76
+ if ttl_seconds is not None:
77
+ # COORDINATION removed in v5.0 - use SESSION for short-lived data
78
+ if ttl_seconds <= TTLStrategy.SESSION.value:
79
+ ttl_strategy = TTLStrategy.SESSION
80
+ elif ttl_seconds <= TTLStrategy.WORKING_RESULTS.value:
81
+ ttl_strategy = TTLStrategy.WORKING_RESULTS
82
+ elif ttl_seconds <= TTLStrategy.STAGED_PATTERNS.value:
83
+ ttl_strategy = TTLStrategy.STAGED_PATTERNS
84
+ else:
85
+ ttl_strategy = TTLStrategy.CONFLICT_CONTEXT
86
+
87
+ try:
88
+ self._short_term.stash(key, value, self.credentials, ttl_strategy)
89
+ except Exception as e:
90
+ logger.debug("redis_stash_failed", key=key, error=str(e))
91
+
92
+ # Return True if at least one backend succeeded
93
+ return self._file_session is not None
94
+
95
+ def retrieve(self, key: str) -> Any | None:
96
+ """Retrieve data from working memory.
97
+
98
+ Checks Redis first (if available) for faster access, then falls back
99
+ to file-based session storage.
100
+
101
+ Args:
102
+ key: Storage key
103
+
104
+ Returns:
105
+ Stored data or None if not found
106
+
107
+ """
108
+ # Try Redis first (faster, if available)
109
+ if self._short_term and self._redis_status and self._redis_status.available:
110
+ try:
111
+ result = self._short_term.retrieve(key, self.credentials)
112
+ if result is not None:
113
+ return result
114
+ except Exception as e:
115
+ logger.debug("redis_retrieve_failed", key=key, error=str(e))
116
+
117
+ # Fall back to file session (primary storage)
118
+ if self._file_session:
119
+ return self._file_session.retrieve(key)
120
+
121
+ return None
122
+
123
+ # =========================================================================
124
+ # PATTERN STAGING
125
+ # =========================================================================
126
+
127
+ def stage_pattern(
128
+ self,
129
+ pattern_data: dict[str, Any],
130
+ pattern_type: str = "general",
131
+ ttl_hours: int = 24,
132
+ ) -> str | None:
133
+ """Stage a pattern for validation before long-term storage.
134
+
135
+ Args:
136
+ pattern_data: Pattern content and metadata
137
+ pattern_type: Type of pattern (algorithm, protocol, etc.)
138
+ ttl_hours: Hours before staged pattern expires (not used in current impl)
139
+
140
+ Returns:
141
+ Staged pattern ID or None if failed
142
+
143
+ """
144
+ from ..short_term import StagedPattern
145
+
146
+ if not self._short_term:
147
+ logger.warning("short_term_memory_unavailable")
148
+ return None
149
+
150
+ # Create a StagedPattern object from the pattern_data dict
151
+ pattern_id = f"staged_{uuid.uuid4().hex[:12]}"
152
+ staged_pattern = StagedPattern(
153
+ pattern_id=pattern_id,
154
+ agent_id=self.user_id,
155
+ pattern_type=pattern_type,
156
+ name=pattern_data.get("name", f"Pattern {pattern_id[:8]}"),
157
+ description=pattern_data.get("description", ""),
158
+ code=pattern_data.get("code"),
159
+ context=pattern_data.get("context", {}),
160
+ confidence=pattern_data.get("confidence", 0.5),
161
+ staged_at=datetime.now(),
162
+ interests=pattern_data.get("interests", []),
163
+ )
164
+ # Store content in context if provided
165
+ if "content" in pattern_data:
166
+ staged_pattern.context["content"] = pattern_data["content"]
167
+
168
+ success = self._short_term.stage_pattern(staged_pattern, self.credentials)
169
+ return pattern_id if success else None
170
+
171
+ def get_staged_patterns(self) -> list[dict]:
172
+ """Get all staged patterns awaiting validation.
173
+
174
+ Returns:
175
+ List of staged patterns with metadata
176
+
177
+ """
178
+ if not self._short_term:
179
+ return []
180
+
181
+ staged_list = self._short_term.list_staged_patterns(self.credentials)
182
+ return [p.to_dict() for p in staged_list]
attune/memory/nodes.py ADDED
@@ -0,0 +1,179 @@
1
+ """Memory Graph Node Types
2
+
3
+ Defines node types for the cross-workflow knowledge graph.
4
+ Each node represents an entity discovered by a workflow.
5
+
6
+ Copyright 2025 Smart AI Memory, LLC
7
+ Licensed under Fair Source 0.9
8
+ """
9
+
10
+ from dataclasses import dataclass, field
11
+ from datetime import datetime
12
+ from enum import Enum
13
+ from typing import Any
14
+
15
+
16
+ class NodeType(Enum):
17
+ """Types of nodes in the memory graph."""
18
+
19
+ # Code entities
20
+ FILE = "file"
21
+ FUNCTION = "function"
22
+ CLASS = "class"
23
+ MODULE = "module"
24
+
25
+ # Issues and findings
26
+ BUG = "bug"
27
+ VULNERABILITY = "vulnerability"
28
+ PERFORMANCE_ISSUE = "performance_issue"
29
+ CODE_SMELL = "code_smell"
30
+ TECH_DEBT = "tech_debt"
31
+
32
+ # Solutions and patterns
33
+ PATTERN = "pattern"
34
+ FIX = "fix"
35
+ REFACTOR = "refactor"
36
+
37
+ # Testing
38
+ TEST = "test"
39
+ TEST_CASE = "test_case"
40
+ COVERAGE_GAP = "coverage_gap"
41
+
42
+ # Documentation
43
+ DOC = "doc"
44
+ API_ENDPOINT = "api_endpoint"
45
+
46
+ # Dependencies
47
+ DEPENDENCY = "dependency"
48
+ LICENSE = "license"
49
+
50
+
51
+ @dataclass
52
+ class Node:
53
+ """A node in the memory graph.
54
+
55
+ Represents any entity that workflows discover or create.
56
+ """
57
+
58
+ id: str
59
+ type: NodeType
60
+ name: str
61
+ description: str = ""
62
+
63
+ # Where this node came from
64
+ source_workflow: str = ""
65
+ source_file: str = ""
66
+ source_line: int | None = None
67
+
68
+ # Classification
69
+ severity: str = "" # critical, high, medium, low, info
70
+ confidence: float = 1.0 # 0.0 - 1.0
71
+
72
+ # Metadata
73
+ metadata: dict[str, Any] = field(default_factory=dict)
74
+ tags: list[str] = field(default_factory=list)
75
+
76
+ # Timestamps
77
+ created_at: datetime = field(default_factory=datetime.now)
78
+ updated_at: datetime = field(default_factory=datetime.now)
79
+
80
+ # Status tracking
81
+ status: str = "open" # open, investigating, resolved, wontfix
82
+
83
+ def to_dict(self) -> dict[str, Any]:
84
+ """Convert node to dictionary for JSON serialization."""
85
+ return {
86
+ "id": self.id,
87
+ "type": self.type.value,
88
+ "name": self.name,
89
+ "description": self.description,
90
+ "source_workflow": self.source_workflow,
91
+ "source_file": self.source_file,
92
+ "source_line": self.source_line,
93
+ "severity": self.severity,
94
+ "confidence": self.confidence,
95
+ "metadata": self.metadata,
96
+ "tags": self.tags,
97
+ "created_at": self.created_at.isoformat(),
98
+ "updated_at": self.updated_at.isoformat(),
99
+ "status": self.status,
100
+ }
101
+
102
+ @classmethod
103
+ def from_dict(cls, data: dict[str, Any]) -> "Node":
104
+ """Create node from dictionary."""
105
+ return cls(
106
+ id=data["id"],
107
+ type=NodeType(data["type"]),
108
+ name=data["name"],
109
+ description=data.get("description", ""),
110
+ source_workflow=data.get("source_workflow", data.get("source_wizard", "")),
111
+ source_file=data.get("source_file", ""),
112
+ source_line=data.get("source_line"),
113
+ severity=data.get("severity", ""),
114
+ confidence=data.get("confidence", 1.0),
115
+ metadata=data.get("metadata", {}),
116
+ tags=data.get("tags", []),
117
+ created_at=(
118
+ datetime.fromisoformat(data["created_at"])
119
+ if "created_at" in data
120
+ else datetime.now()
121
+ ),
122
+ updated_at=(
123
+ datetime.fromisoformat(data["updated_at"])
124
+ if "updated_at" in data
125
+ else datetime.now()
126
+ ),
127
+ status=data.get("status", "open"),
128
+ )
129
+
130
+
131
+ @dataclass
132
+ class BugNode(Node):
133
+ """Specialized node for bugs."""
134
+
135
+ root_cause: str = ""
136
+ fix_suggestion: str = ""
137
+ reproduction_steps: list[str] = field(default_factory=list)
138
+
139
+ def __post_init__(self):
140
+ self.type = NodeType.BUG
141
+
142
+
143
+ @dataclass
144
+ class VulnerabilityNode(Node):
145
+ """Specialized node for security vulnerabilities."""
146
+
147
+ cwe_id: str = ""
148
+ cvss_score: float = 0.0
149
+ attack_vector: str = ""
150
+ remediation: str = ""
151
+
152
+ def __post_init__(self):
153
+ self.type = NodeType.VULNERABILITY
154
+
155
+
156
+ @dataclass
157
+ class PerformanceNode(Node):
158
+ """Specialized node for performance issues."""
159
+
160
+ metric: str = "" # latency, memory, cpu, etc.
161
+ current_value: float = 0.0
162
+ target_value: float = 0.0
163
+ optimization_suggestion: str = ""
164
+
165
+ def __post_init__(self):
166
+ self.type = NodeType.PERFORMANCE_ISSUE
167
+
168
+
169
+ @dataclass
170
+ class PatternNode(Node):
171
+ """Specialized node for code patterns."""
172
+
173
+ pattern_type: str = "" # anti-pattern, best-practice, idiom
174
+ language: str = ""
175
+ example_code: str = ""
176
+ applies_to: list[str] = field(default_factory=list)
177
+
178
+ def __post_init__(self):
179
+ self.type = NodeType.PATTERN