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,363 @@
1
+ """Base class for LLM-enhanced workflow generation.
2
+
3
+ Provides reusable patterns for hybrid LLM + template generation with:
4
+ - Smart caching for expensive operations
5
+ - Fallback to templates when LLM fails
6
+ - Quality validation
7
+ - Dashboard integration
8
+ - Cost tracking
9
+
10
+ Copyright 2026 Smart-AI-Memory
11
+ Licensed under Apache 2.0
12
+ """
13
+
14
+ import hashlib
15
+ import json
16
+ import logging
17
+ import os
18
+ from abc import ABC, abstractmethod
19
+ from datetime import datetime, timedelta
20
+ from typing import Any
21
+
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class LLMWorkflowGenerator(ABC):
26
+ """Base class for LLM-enhanced workflow generation.
27
+
28
+ Provides hybrid approach: intelligent LLM generation with fallback templates.
29
+
30
+ Usage:
31
+ class TestGeneratorLLM(LLMWorkflowGenerator):
32
+ def _generate_with_template(self, context: dict) -> str:
33
+ return create_template(context)
34
+
35
+ def _validate(self, result: str) -> bool:
36
+ return validate_python_syntax(result)
37
+
38
+ generator = TestGeneratorLLM(model_tier="capable")
39
+ output = generator.generate(context, prompt)
40
+ """
41
+
42
+ def __init__(
43
+ self,
44
+ model_tier: str = "capable",
45
+ enable_cache: bool = True,
46
+ cache_ttl_hours: int = 24,
47
+ ):
48
+ """Initialize LLM workflow generator.
49
+
50
+ Args:
51
+ model_tier: Model tier to use (cheap, capable, premium)
52
+ enable_cache: Whether to cache LLM responses
53
+ cache_ttl_hours: Cache time-to-live in hours
54
+ """
55
+ self.model_tier = model_tier
56
+ self.enable_cache = enable_cache
57
+ self.cache_ttl = timedelta(hours=cache_ttl_hours)
58
+ self._cache: dict[str, tuple[str, datetime]] = {}
59
+ self._stats = {
60
+ "llm_requests": 0,
61
+ "llm_failures": 0,
62
+ "template_fallbacks": 0,
63
+ "cache_hits": 0,
64
+ "cache_misses": 0,
65
+ "total_tokens": 0,
66
+ "total_cost_usd": 0.0,
67
+ }
68
+
69
+ def generate(self, context: dict[str, Any], prompt: str) -> str:
70
+ """Generate output with LLM, fallback to template.
71
+
72
+ Args:
73
+ context: Context dict for generation
74
+ prompt: LLM prompt
75
+
76
+ Returns:
77
+ Generated output (from LLM or template)
78
+ """
79
+ # Check cache first
80
+ if self.enable_cache:
81
+ cache_key = self._make_cache_key(context, prompt)
82
+ cached = self._get_from_cache(cache_key)
83
+ if cached:
84
+ self._stats["cache_hits"] += 1
85
+ logger.debug(f"Cache hit for {cache_key[:16]}...")
86
+ return cached
87
+ self._stats["cache_misses"] += 1
88
+
89
+ # Try LLM generation
90
+ try:
91
+ self._stats["llm_requests"] += 1
92
+ result = self._generate_with_llm(prompt)
93
+
94
+ # Validate result
95
+ if self._validate(result):
96
+ # Cache successful result
97
+ if self.enable_cache:
98
+ self._put_in_cache(cache_key, result)
99
+
100
+ # Track tokens and cost
101
+ self._update_usage_stats(result)
102
+
103
+ logger.info("LLM generation successful")
104
+ return result
105
+ else:
106
+ logger.warning("LLM result failed validation")
107
+
108
+ except Exception as e:
109
+ self._stats["llm_failures"] += 1
110
+ logger.warning(f"LLM generation failed: {e}")
111
+
112
+ # Fallback to template
113
+ self._stats["template_fallbacks"] += 1
114
+ logger.info("Falling back to template generation")
115
+ return self._generate_with_template(context)
116
+
117
+ def _generate_with_llm(self, prompt: str) -> str:
118
+ """Generate using LLM API.
119
+
120
+ Args:
121
+ prompt: LLM prompt
122
+
123
+ Returns:
124
+ Generated content
125
+
126
+ Raises:
127
+ Exception: If LLM generation fails
128
+ """
129
+ try:
130
+ import anthropic
131
+ except ImportError:
132
+ raise ImportError("anthropic package not installed")
133
+
134
+ # Get API key
135
+ api_key = os.getenv("ANTHROPIC_API_KEY")
136
+ if not api_key:
137
+ raise ValueError("ANTHROPIC_API_KEY not set")
138
+
139
+ # Get model ID for tier
140
+ model_id = self._get_model_id(self.model_tier)
141
+
142
+ # Call Anthropic API
143
+ logger.debug(f"Calling LLM with {self.model_tier} tier (model: {model_id})")
144
+ client = anthropic.Anthropic(api_key=api_key)
145
+ response = client.messages.create(
146
+ model=model_id,
147
+ max_tokens=4000,
148
+ messages=[{"role": "user", "content": prompt}],
149
+ )
150
+
151
+ if not response.content:
152
+ raise ValueError("Empty LLM response")
153
+
154
+ result = response.content[0].text.strip()
155
+
156
+ # Clean up markdown fences if present
157
+ if result.startswith("```python"):
158
+ result = result[len("```python") :].strip()
159
+ elif result.startswith("```"):
160
+ result = result[3:].strip()
161
+ if result.endswith("```"):
162
+ result = result[:-3].strip()
163
+
164
+ return result
165
+
166
+ def _get_model_id(self, tier: str) -> str:
167
+ """Get model ID for tier.
168
+
169
+ Args:
170
+ tier: Model tier (cheap, capable, premium)
171
+
172
+ Returns:
173
+ Model ID string
174
+ """
175
+ from attune.models.registry import get_model
176
+
177
+ model_info = get_model("anthropic", tier)
178
+ if not model_info:
179
+ raise ValueError(f"No model found for tier: {tier}")
180
+
181
+ return model_info.model_id
182
+
183
+ def _make_cache_key(self, context: dict[str, Any], prompt: str) -> str:
184
+ """Create cache key from context and prompt.
185
+
186
+ Args:
187
+ context: Context dict
188
+ prompt: Prompt string
189
+
190
+ Returns:
191
+ Cache key (hex hash)
192
+ """
193
+ # Combine context and prompt for cache key
194
+ cache_data = {
195
+ "context": context,
196
+ "prompt": prompt,
197
+ "model_tier": self.model_tier,
198
+ }
199
+ cache_json = json.dumps(cache_data, sort_keys=True)
200
+ return hashlib.sha256(cache_json.encode()).hexdigest()
201
+
202
+ def _get_from_cache(self, cache_key: str) -> str | None:
203
+ """Get item from cache if not expired.
204
+
205
+ Args:
206
+ cache_key: Cache key
207
+
208
+ Returns:
209
+ Cached value or None if not found/expired
210
+ """
211
+ if cache_key not in self._cache:
212
+ return None
213
+
214
+ value, timestamp = self._cache[cache_key]
215
+
216
+ # Check if expired
217
+ if datetime.now() - timestamp > self.cache_ttl:
218
+ del self._cache[cache_key]
219
+ return None
220
+
221
+ return value
222
+
223
+ def _put_in_cache(self, cache_key: str, value: str):
224
+ """Put item in cache with current timestamp.
225
+
226
+ Args:
227
+ cache_key: Cache key
228
+ value: Value to cache
229
+ """
230
+ self._cache[cache_key] = (value, datetime.now())
231
+
232
+ def _update_usage_stats(self, result: str):
233
+ """Update token and cost statistics.
234
+
235
+ Args:
236
+ result: Generated result
237
+ """
238
+ # Rough token estimate (4 chars per token)
239
+ estimated_tokens = len(result) // 4
240
+ self._stats["total_tokens"] += estimated_tokens
241
+
242
+ # Cost estimation (based on capable tier: $3/M input, $15/M output)
243
+ if self.model_tier == "cheap":
244
+ cost_per_token = 1.0 / 1_000_000 # $1/M tokens
245
+ elif self.model_tier == "capable":
246
+ cost_per_token = 15.0 / 1_000_000 # $15/M output tokens
247
+ elif self.model_tier == "premium":
248
+ cost_per_token = 75.0 / 1_000_000 # $75/M output tokens
249
+ else:
250
+ cost_per_token = 15.0 / 1_000_000
251
+
252
+ self._stats["total_cost_usd"] += estimated_tokens * cost_per_token
253
+
254
+ def get_stats(self) -> dict[str, Any]:
255
+ """Get generation statistics.
256
+
257
+ Returns:
258
+ Dict with usage stats
259
+ """
260
+ stats = self._stats.copy()
261
+
262
+ # Calculate rates
263
+ total_requests = stats["llm_requests"]
264
+ if total_requests > 0:
265
+ stats["llm_success_rate"] = (
266
+ total_requests - stats["llm_failures"]
267
+ ) / total_requests
268
+ stats["template_fallback_rate"] = stats["template_fallbacks"] / total_requests
269
+ else:
270
+ stats["llm_success_rate"] = 0.0
271
+ stats["template_fallback_rate"] = 0.0
272
+
273
+ # Cache performance
274
+ total_cache_ops = stats["cache_hits"] + stats["cache_misses"]
275
+ if total_cache_ops > 0:
276
+ stats["cache_hit_rate"] = stats["cache_hits"] / total_cache_ops
277
+ else:
278
+ stats["cache_hit_rate"] = 0.0
279
+
280
+ return stats
281
+
282
+ def clear_cache(self):
283
+ """Clear the cache."""
284
+ self._cache.clear()
285
+ logger.info("Cache cleared")
286
+
287
+ @abstractmethod
288
+ def _generate_with_template(self, context: dict[str, Any]) -> str:
289
+ """Generate using template fallback.
290
+
291
+ Args:
292
+ context: Context dict with generation data
293
+
294
+ Returns:
295
+ Generated output from template
296
+
297
+ Note:
298
+ Subclasses must implement this method.
299
+ """
300
+ raise NotImplementedError("Subclass must implement _generate_with_template")
301
+
302
+ @abstractmethod
303
+ def _validate(self, result: str) -> bool:
304
+ """Validate generated output.
305
+
306
+ Args:
307
+ result: Generated output to validate
308
+
309
+ Returns:
310
+ True if valid, False otherwise
311
+
312
+ Note:
313
+ Subclasses must implement this method.
314
+ """
315
+ raise NotImplementedError("Subclass must implement _validate")
316
+
317
+
318
+ class TestGeneratorLLM(LLMWorkflowGenerator):
319
+ """Example LLM-enhanced test generator.
320
+
321
+ Shows how to use the base class for test generation.
322
+ """
323
+
324
+ def _generate_with_template(self, context: dict[str, Any]) -> str:
325
+ """Fallback template generation.
326
+
327
+ Args:
328
+ context: Must contain 'module_name', 'module_path'
329
+
330
+ Returns:
331
+ Template test file
332
+ """
333
+ module_name = context.get("module_name", "unknown")
334
+ module_path = context.get("module_path", "unknown")
335
+
336
+ return f'''"""Behavioral tests for {module_name}.
337
+
338
+ Generated by template fallback.
339
+
340
+ Copyright 2026 Smart-AI-Memory
341
+ Licensed under Apache 2.0
342
+ """
343
+
344
+ import pytest
345
+
346
+ def test_{module_name}_placeholder():
347
+ """Placeholder test - implement actual tests."""
348
+ # TODO: Implement comprehensive tests
349
+ pass
350
+ '''
351
+
352
+ def _validate(self, result: str) -> bool:
353
+ """Validate test file has basic structure.
354
+
355
+ Args:
356
+ result: Generated test file content
357
+
358
+ Returns:
359
+ True if valid test file structure
360
+ """
361
+ # Check for basic test file structure
362
+ required = ["import pytest", "def test_", '"""']
363
+ return all(req in result for req in required) and len(result) > 100
@@ -0,0 +1,87 @@
1
+ """Manage documentation
2
+
3
+ Stages:
4
+ 1. process - Process
5
+
6
+ Copyright 2025 Smart-AI-Memory
7
+ Licensed under Fair Source License 0.9
8
+ """
9
+
10
+ import logging
11
+ from typing import Any
12
+
13
+ from attune.workflows.base import BaseWorkflow, ModelTier
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class ManageDocsWorkflow(BaseWorkflow):
19
+ """Manage documentation
20
+
21
+
22
+ Usage:
23
+ workflow = ManageDocsWorkflow()
24
+ result = await workflow.execute(
25
+ # Add parameters here
26
+ )
27
+ """
28
+
29
+ name = "manage-docs"
30
+ description = "Manage documentation"
31
+ stages = ["process"]
32
+ tier_map = {
33
+ "process": ModelTier.CAPABLE,
34
+ }
35
+
36
+ def __init__(
37
+ self,
38
+ **kwargs: Any,
39
+ ):
40
+ """Initialize manage-docs workflow.
41
+
42
+ Args:
43
+ **kwargs: Additional arguments passed to BaseWorkflow
44
+
45
+ """
46
+ super().__init__(**kwargs)
47
+
48
+ async def run_stage(
49
+ self,
50
+ stage_name: str,
51
+ tier: ModelTier,
52
+ input_data: Any,
53
+ ) -> tuple[Any, int, int]:
54
+ """Execute the single processing stage."""
55
+ if stage_name == "process":
56
+ return await self._process(input_data, tier)
57
+ raise ValueError(f"Unknown stage: {stage_name}")
58
+
59
+ async def _process(
60
+ self,
61
+ input_data: Any,
62
+ tier: ModelTier,
63
+ ) -> tuple[Any, int, int]:
64
+ """Process the input data.
65
+
66
+ Args:
67
+ input_data: Input data to process
68
+ tier: Model tier to use
69
+
70
+ Returns:
71
+ Tuple of (result, input_tokens, output_tokens)
72
+
73
+ """
74
+ # TODO: Implement processing logic
75
+ prompt = f"Process this input: {input_data}"
76
+
77
+ # Use LLM executor if available
78
+ if self._executor:
79
+ result = await self._executor.run(
80
+ task_type="workflow_stage",
81
+ prompt=prompt,
82
+ tier=tier.to_unified() if hasattr(tier, "to_unified") else tier,
83
+ )
84
+ return result.content, result.input_tokens, result.output_tokens
85
+
86
+ # Fallback to basic processing
87
+ return {"result": "Processed", "input": input_data}, 0, 0
@@ -0,0 +1,134 @@
1
+ # ManageDocsWorkflow
2
+
3
+ **Manage documentation**
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ **Patterns Used:**
10
+ - `single-stage` - Simple one-stage workflow with single tier
11
+
12
+ **Complexity:** SIMPLE
13
+
14
+ **Stages:**
15
+ 1. **process** - CAPABLE tier
16
+
17
+ ---
18
+
19
+ ## Usage
20
+
21
+ ```python
22
+ from attune.workflows.manage_docs import ManageDocsWorkflow
23
+
24
+ # Initialize workflow
25
+ workflow = ManageDocsWorkflow(
26
+ )
27
+
28
+ # Execute
29
+ result = await workflow.execute(
30
+ # Add your input data here
31
+ )
32
+
33
+ # Check result
34
+ print(f"Success: {result.success}")
35
+ ```
36
+
37
+ ---
38
+
39
+ ## CLI Usage
40
+
41
+ ```bash
42
+ # Run via empathy CLI
43
+ empathy workflow run manage-docs --input '{"key": "value"}'
44
+
45
+ # With options
46
+ ```
47
+
48
+ ---
49
+
50
+ ## Configuration
51
+
52
+ This workflow does not use configuration files.
53
+
54
+ ---
55
+
56
+ ## Stages
57
+
58
+ ### 1. Process
59
+
60
+ **Tier:** CAPABLE
61
+
62
+ **Purpose:** TODO: Add description
63
+ **Input:** TODO: Add description
64
+ **Output:** TODO: Add description
65
+
66
+ ---
67
+
68
+ ## Testing
69
+
70
+ ```bash
71
+ # Run tests
72
+ pytest tests/unit/workflows/test_manage_docs.py -v
73
+
74
+ # Run with coverage
75
+ pytest tests/unit/workflows/test_manage_docs.py --cov
76
+
77
+ # Run specific test
78
+ pytest tests/unit/workflows/test_manage_docs.py::TestManageDocsWorkflow::test_workflow_execution_basic -v
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Cost Optimization
84
+
85
+ **Tier Distribution:**
86
+ - CHEAP: 0 stage(s)
87
+ - CAPABLE: 1 stage(s)
88
+ - PREMIUM: 0 stage(s)
89
+
90
+ ---
91
+
92
+ ## Examples
93
+
94
+ ### Example 1: Basic Usage
95
+
96
+ ```python
97
+ workflow = ManageDocsWorkflow()
98
+ result = await workflow.execute(
99
+ # TODO: Add example input
100
+ )
101
+ ```
102
+
103
+ ### Example 2: With Custom Settings
104
+
105
+ ```python
106
+ workflow = ManageDocsWorkflow(
107
+ )
108
+ result = await workflow.execute(
109
+ # TODO: Add example input
110
+ )
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Troubleshooting
116
+
117
+ ### Common Issues
118
+
119
+ **Issue:** Workflow fails with "X not found"
120
+ **Solution:** TODO: Add solution
121
+
122
+ **Issue:** High costs
123
+ **Solution:** Consider adding conditional tier routing
124
+ ---
125
+
126
+ ## Related Workflows
127
+
128
+ - TODO: Add related workflows
129
+
130
+ ---
131
+
132
+ **Generated:** 2026-01-09
133
+ **Patterns:** single-stage
134
+ **Complexity:** SIMPLE