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,240 @@
1
+ """CLI for workflow scaffolding.
2
+
3
+ Usage:
4
+ python -m scaffolding create my_workflow --domain healthcare
5
+ python -m scaffolding create my_workflow --methodology tdd --domain finance
6
+ python -m scaffolding create my_workflow --interactive
7
+
8
+ Copyright 2025 Smart AI Memory, LLC
9
+ Licensed under Fair Source 0.9
10
+ """
11
+
12
+ import argparse
13
+ import logging
14
+ import sys
15
+
16
+ from patterns import get_pattern_registry
17
+
18
+ from .methodologies.pattern_compose import PatternCompose
19
+ from .methodologies.tdd_first import TDDFirst
20
+
21
+ logging.basicConfig(
22
+ level=logging.INFO,
23
+ format="%(levelname)s: %(message)s",
24
+ )
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ def cmd_create(args):
29
+ """Create a new workflow using specified methodology.
30
+
31
+ Args:
32
+ args: Command line arguments
33
+
34
+ """
35
+ workflow_name = args.name
36
+ domain = args.domain or "general"
37
+ workflow_type = args.type or "domain"
38
+ methodology = args.methodology or "pattern"
39
+
40
+ print(f"\n{'=' * 60}")
41
+ print(f"Creating Workflow: {workflow_name}")
42
+ print(f"{'=' * 60}\n")
43
+ print(f"Domain: {domain}")
44
+ print(f"Type: {workflow_type}")
45
+ print(f"Methodology: {methodology}")
46
+ print()
47
+
48
+ # Get pattern recommendations
49
+ registry = get_pattern_registry()
50
+ recommended = registry.recommend_for_workflow(
51
+ workflow_type=workflow_type,
52
+ domain=domain,
53
+ )
54
+
55
+ print(f"Recommended Patterns ({len(recommended)}):")
56
+ for i, pattern in enumerate(recommended, 1):
57
+ print(f" {i}. {pattern.name} - {pattern.description[:60]}...")
58
+
59
+ # Pattern selection
60
+ if args.patterns:
61
+ # User provided patterns
62
+ selected_patterns = args.patterns.split(",")
63
+ elif args.interactive:
64
+ # Interactive selection
65
+ print("\nSelect patterns (comma-separated numbers, or 'all' for all):")
66
+ selection = input("> ").strip()
67
+
68
+ if selection.lower() == "all":
69
+ selected_patterns = [p.id for p in recommended]
70
+ else:
71
+ try:
72
+ indices = [int(i.strip()) - 1 for i in selection.split(",")]
73
+ selected_patterns = [recommended[i].id for i in indices]
74
+ except (ValueError, IndexError):
75
+ print("Invalid selection. Using all patterns.")
76
+ selected_patterns = [p.id for p in recommended]
77
+ else:
78
+ # Use all recommended
79
+ selected_patterns = [p.id for p in recommended]
80
+
81
+ print(f"\nUsing {len(selected_patterns)} patterns:")
82
+ for pid in selected_patterns:
83
+ print(f" - {pid}")
84
+
85
+ # Create workflow using selected methodology
86
+ print(f"\nCreating workflow with {methodology} methodology...")
87
+
88
+ if methodology == "pattern":
89
+ method = PatternCompose()
90
+ result = method.create_workflow(
91
+ name=workflow_name,
92
+ domain=domain,
93
+ workflow_type=workflow_type,
94
+ selected_patterns=selected_patterns,
95
+ )
96
+ elif methodology == "tdd":
97
+ method = TDDFirst()
98
+ result = method.create_workflow(
99
+ name=workflow_name,
100
+ domain=domain,
101
+ workflow_type=workflow_type,
102
+ pattern_ids=selected_patterns,
103
+ )
104
+ else:
105
+ print(f"Unknown methodology: {methodology}")
106
+ sys.exit(1)
107
+
108
+ # Display results
109
+ print(f"\n{'=' * 60}")
110
+ print("✅ Workflow Created Successfully!")
111
+ print(f"{'=' * 60}\n")
112
+
113
+ print("Generated Files:")
114
+ for file_path in result["files"]:
115
+ print(f" - {file_path}")
116
+
117
+ print("\nPatterns Used:")
118
+ for pattern_name in result.get("patterns", selected_patterns):
119
+ print(f" - {pattern_name}")
120
+
121
+ print("\nNext Steps:")
122
+ for step in result["next_steps"]:
123
+ print(f" {step}")
124
+
125
+ print()
126
+
127
+
128
+ def cmd_list_patterns(args):
129
+ """List available patterns.
130
+
131
+ Args:
132
+ args: Command line arguments
133
+
134
+ """
135
+ registry = get_pattern_registry()
136
+
137
+ print(f"\n{'=' * 60}")
138
+ print("Available Patterns")
139
+ print(f"{'=' * 60}\n")
140
+
141
+ # Group by category
142
+ from patterns.core import PatternCategory
143
+
144
+ for category in PatternCategory:
145
+ patterns = registry.list_by_category(category)
146
+ if not patterns:
147
+ continue
148
+
149
+ print(f"{category.value.upper()} ({len(patterns)} patterns):")
150
+ for pattern in patterns:
151
+ print(
152
+ f" - {pattern.id:25} | {pattern.name:20} | Reusability: {pattern.reusability_score:.2f}"
153
+ )
154
+ print()
155
+
156
+ stats = registry.get_statistics()
157
+ print(f"Total: {stats['total_patterns']} patterns")
158
+ print(f"Average Reusability: {stats['average_reusability']:.2f}")
159
+ print()
160
+
161
+
162
+ def main():
163
+ """Main CLI entry point."""
164
+ parser = argparse.ArgumentParser(
165
+ description="Workflow Scaffolding for Empathy Framework",
166
+ formatter_class=argparse.RawDescriptionHelpFormatter,
167
+ epilog="""
168
+ Examples:
169
+ # Create healthcare workflow (recommended approach)
170
+ %(prog)s create patient_intake --domain healthcare
171
+
172
+ # Create with TDD methodology
173
+ %(prog)s create my_workflow --methodology tdd --domain finance
174
+
175
+ # Interactive pattern selection
176
+ %(prog)s create my_workflow --interactive --domain legal
177
+
178
+ # Specify patterns manually
179
+ %(prog)s create my_workflow --patterns linear_flow,approval,structured_fields
180
+
181
+ # List available patterns
182
+ %(prog)s list-patterns
183
+ """,
184
+ )
185
+
186
+ subparsers = parser.add_subparsers(dest="command", help="Command to run")
187
+
188
+ # Create command
189
+ create_parser = subparsers.add_parser("create", help="Create a new workflow")
190
+ create_parser.add_argument("name", help="Workflow name (e.g., patient_intake)")
191
+ create_parser.add_argument(
192
+ "--domain",
193
+ "-d",
194
+ help="Domain (e.g., healthcare, finance, legal)",
195
+ )
196
+ create_parser.add_argument(
197
+ "--type",
198
+ "-t",
199
+ choices=["domain", "coach", "ai"],
200
+ help="Workflow type (default: domain)",
201
+ )
202
+ create_parser.add_argument(
203
+ "--methodology",
204
+ "-m",
205
+ choices=["pattern", "tdd"],
206
+ help="Methodology (default: pattern)",
207
+ )
208
+ create_parser.add_argument(
209
+ "--patterns",
210
+ "-p",
211
+ help="Comma-separated pattern IDs",
212
+ )
213
+ create_parser.add_argument(
214
+ "--interactive",
215
+ "-i",
216
+ action="store_true",
217
+ help="Interactive pattern selection",
218
+ )
219
+
220
+ # List patterns command
221
+ subparsers.add_parser("list-patterns", help="List available patterns")
222
+
223
+ args = parser.parse_args()
224
+
225
+ if not args.command:
226
+ parser.print_help()
227
+ sys.exit(1)
228
+
229
+ # Execute command
230
+ if args.command == "create":
231
+ cmd_create(args)
232
+ elif args.command == "list-patterns":
233
+ cmd_list_patterns(args)
234
+ else:
235
+ parser.print_help()
236
+ sys.exit(1)
237
+
238
+
239
+ if __name__ == "__main__":
240
+ main()
@@ -0,0 +1,121 @@
1
+ """{{ wizard_name | title | replace('_', ' ') }} Wizard.
2
+
3
+ Auto-generated by Empathy Framework Scaffolding
4
+ Methodology: {{ methodology }}
5
+ Domain: {{ domain }}
6
+ Type: {{ wizard_type }}
7
+ Patterns: {{ pattern_ids | join(', ') }}
8
+ Generated: {{ timestamp }}
9
+ """
10
+
11
+ import logging
12
+ from typing import Any
13
+
14
+ from fastapi import APIRouter, HTTPException
15
+ from pydantic import BaseModel, Field
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ router = APIRouter(prefix="/{{ wizard_name }}", tags=["{{ wizard_name }}"])
20
+
21
+
22
+ # Request/Response Models
23
+ class ProcessRequest(BaseModel):
24
+ """Request to process wizard input."""
25
+ data: dict[str, Any] = Field(..., description="Input data to process")
26
+ context: dict[str, Any] = Field(default_factory=dict, description="Additional context")
27
+
28
+
29
+ class ProcessResult(BaseModel):
30
+ """Wizard processing result."""
31
+ wizard_id: str
32
+ result: dict[str, Any]
33
+ status: str = "success"
34
+
35
+
36
+ # In-memory session storage (replace with Redis in production)
37
+ sessions: dict[str, dict[str, Any]] = {}
38
+
39
+
40
+ @router.post("/process", response_model=ProcessResult)
41
+ async def process(request: ProcessRequest) -> ProcessResult:
42
+ """Process wizard input.
43
+
44
+ Args:
45
+ request: Processing request with input data
46
+
47
+ Returns:
48
+ Processing result
49
+
50
+ Raises:
51
+ HTTPException: If processing fails
52
+ """
53
+ try:
54
+ # Create session
55
+ wizard_id = f"{{ wizard_name }}_{len(sessions) + 1}"
56
+
57
+ # Process data
58
+ result = await _process_data(request.data, request.context)
59
+
60
+ # Store session
61
+ sessions[wizard_id] = {
62
+ "wizard_id": wizard_id,
63
+ "input_data": request.data,
64
+ "context": request.context,
65
+ "result": result,
66
+ }
67
+
68
+ logger.info(f"Processing complete for {wizard_id}")
69
+
70
+ return ProcessResult(
71
+ wizard_id=wizard_id,
72
+ result=result,
73
+ status="success",
74
+ )
75
+
76
+ except Exception as e:
77
+ logger.exception(f"Processing failed: {e}")
78
+ raise HTTPException(status_code=500, detail=f"Processing failed: {str(e)}")
79
+
80
+
81
+ @router.get("/{wizard_id}/result", response_model=dict[str, Any])
82
+ async def get_result(wizard_id: str) -> dict[str, Any]:
83
+ """Get wizard result.
84
+
85
+ Args:
86
+ wizard_id: Wizard session ID
87
+
88
+ Returns:
89
+ Complete wizard result
90
+
91
+ Raises:
92
+ HTTPException: If session not found
93
+ """
94
+ if wizard_id not in sessions:
95
+ raise HTTPException(status_code=404, detail="Session not found")
96
+
97
+ session = sessions[wizard_id]
98
+ return {
99
+ "wizard_id": wizard_id,
100
+ "input_data": session["input_data"],
101
+ "result": session["result"],
102
+ }
103
+
104
+
105
+ # Helper functions
106
+ async def _process_data(data: dict[str, Any], context: dict[str, Any]) -> dict[str, Any]:
107
+ """Process wizard data.
108
+
109
+ Args:
110
+ data: Input data to process
111
+ context: Additional context
112
+
113
+ Returns:
114
+ Processing result
115
+ """
116
+ # TODO: Implement actual processing logic
117
+ return {
118
+ "processed": True,
119
+ "data": data,
120
+ "context": context,
121
+ }
@@ -0,0 +1,321 @@
1
+ """{{ wizard_name | title | replace('_', ' ') }} Coach Wizard.
2
+
3
+ Auto-generated by Empathy Framework Scaffolding
4
+ Methodology: {{ methodology }}
5
+ Domain: {{ domain }}
6
+ Patterns: {{ pattern_ids | join(', ') }}
7
+ Generated: {{ timestamp }}
8
+ """
9
+
10
+ import logging
11
+ from typing import Any
12
+
13
+ from fastapi import APIRouter, HTTPException
14
+ from pydantic import BaseModel, Field
15
+
16
+ from empathy_llm_toolkit.memory_manager import MemoryManager
17
+ from patterns import get_pattern_registry
18
+
19
+ logger = logging.getLogger(__name__)
20
+
21
+ router = APIRouter(prefix="/{{ wizard_name }}", tags=["{{ wizard_name }}"])
22
+
23
+ # Pattern registry for recommendations
24
+ registry = get_pattern_registry()
25
+
26
+
27
+ # Request/Response Models
28
+ class AnalysisRequest(BaseModel):
29
+ """Request to analyze code."""
30
+ code: str = Field(..., description="Code to analyze")
31
+ context: dict[str, Any] = Field(default_factory=dict, description="Additional context")
32
+ {% if 'risk_assessment' in pattern_ids %}
33
+ include_risk_assessment: bool = Field(default=True, description="Include risk analysis")
34
+ {% endif %}
35
+
36
+
37
+ class AnalysisResult(BaseModel):
38
+ """Analysis result."""
39
+ wizard_id: str
40
+ analysis: dict[str, Any]
41
+ {% if 'risk_assessment' in pattern_ids %}
42
+ risk_assessment: dict[str, Any] | None = None
43
+ {% endif %}
44
+ {% if 'prediction' in pattern_ids %}
45
+ predictions: list[dict[str, Any]] = Field(default_factory=list)
46
+ {% endif %}
47
+ {% if 'fix_application' in pattern_ids %}
48
+ suggested_fixes: list[dict[str, Any]] = Field(default_factory=list)
49
+ {% endif %}
50
+
51
+
52
+ {% if 'fix_application' in pattern_ids %}
53
+ class FixRequest(BaseModel):
54
+ """Request to apply a fix."""
55
+ wizard_id: str
56
+ fix_id: str
57
+ approval: dict[str, Any] = Field(..., description="User approval data")
58
+
59
+
60
+ class FixResult(BaseModel):
61
+ """Fix application result."""
62
+ wizard_id: str
63
+ fix_id: str
64
+ applied: bool
65
+ modified_code: str | None = None
66
+ error: str | None = None
67
+ {% endif %}
68
+
69
+
70
+ # In-memory session storage (replace with Redis in production)
71
+ sessions: dict[str, dict[str, Any]] = {}
72
+
73
+
74
+ @router.post("/analyze", response_model=AnalysisResult)
75
+ async def analyze_code(request: AnalysisRequest) -> AnalysisResult:
76
+ """Analyze code and provide recommendations.
77
+
78
+ Args:
79
+ request: Analysis request with code and context
80
+
81
+ Returns:
82
+ Analysis results with recommendations
83
+
84
+ Raises:
85
+ HTTPException: If analysis fails
86
+ """
87
+ try:
88
+ # Create session
89
+ wizard_id = f"{{ wizard_name }}_{len(sessions) + 1}"
90
+
91
+ # Perform code analysis
92
+ analysis = await _analyze_code(request.code, request.context)
93
+
94
+ result = AnalysisResult(
95
+ wizard_id=wizard_id,
96
+ analysis=analysis,
97
+ )
98
+
99
+ {% if 'risk_assessment' in pattern_ids %}
100
+ # Perform risk assessment
101
+ if request.include_risk_assessment:
102
+ risk_assessment = await _assess_risk(analysis)
103
+ result.risk_assessment = risk_assessment
104
+ {% endif %}
105
+
106
+ {% if 'prediction' in pattern_ids %}
107
+ # Generate predictions
108
+ predictions = await _generate_predictions(analysis)
109
+ result.predictions = predictions
110
+ {% endif %}
111
+
112
+ {% if 'fix_application' in pattern_ids %}
113
+ # Suggest fixes
114
+ fixes = await _suggest_fixes(analysis)
115
+ result.suggested_fixes = fixes
116
+ {% endif %}
117
+
118
+ # Store session
119
+ sessions[wizard_id] = {
120
+ "wizard_id": wizard_id,
121
+ "code": request.code,
122
+ "analysis": analysis,
123
+ "result": result.model_dump(),
124
+ }
125
+
126
+ logger.info(f"Analysis complete for {wizard_id}")
127
+ return result
128
+
129
+ except Exception as e:
130
+ logger.exception(f"Analysis failed: {e}")
131
+ raise HTTPException(status_code=500, detail=f"Analysis failed: {str(e)}")
132
+
133
+
134
+ {% if 'fix_application' in pattern_ids %}
135
+ @router.post("/fix/apply", response_model=FixResult)
136
+ async def apply_fix(request: FixRequest) -> FixResult:
137
+ """Apply a suggested fix to code.
138
+
139
+ Args:
140
+ request: Fix application request
141
+
142
+ Returns:
143
+ Fix application result
144
+
145
+ Raises:
146
+ HTTPException: If session not found or fix fails
147
+ """
148
+ # Validate session
149
+ if request.wizard_id not in sessions:
150
+ raise HTTPException(status_code=404, detail="Session not found")
151
+
152
+ session = sessions[request.wizard_id]
153
+
154
+ try:
155
+ # Validate approval
156
+ if not request.approval.get("user_approved"):
157
+ raise HTTPException(status_code=400, detail="User approval required")
158
+
159
+ # Find fix
160
+ suggested_fixes = session["result"].get("suggested_fixes", [])
161
+ fix = next((f for f in suggested_fixes if f["id"] == request.fix_id), None)
162
+
163
+ if not fix:
164
+ raise HTTPException(status_code=404, detail="Fix not found")
165
+
166
+ # Apply fix (placeholder - implement actual fix application)
167
+ modified_code = await _apply_fix(session["code"], fix)
168
+
169
+ # Update session
170
+ session["modified_code"] = modified_code
171
+ session["applied_fixes"] = session.get("applied_fixes", []) + [request.fix_id]
172
+
173
+ logger.info(f"Fix {request.fix_id} applied for {request.wizard_id}")
174
+
175
+ return FixResult(
176
+ wizard_id=request.wizard_id,
177
+ fix_id=request.fix_id,
178
+ applied=True,
179
+ modified_code=modified_code,
180
+ )
181
+
182
+ except HTTPException:
183
+ raise
184
+ except Exception as e:
185
+ logger.exception(f"Fix application failed: {e}")
186
+ return FixResult(
187
+ wizard_id=request.wizard_id,
188
+ fix_id=request.fix_id,
189
+ applied=False,
190
+ error=str(e),
191
+ )
192
+ {% endif %}
193
+
194
+
195
+ @router.get("/{wizard_id}/report", response_model=dict[str, Any])
196
+ async def get_report(wizard_id: str) -> dict[str, Any]:
197
+ """Get analysis report.
198
+
199
+ Args:
200
+ wizard_id: Wizard session ID
201
+
202
+ Returns:
203
+ Complete analysis report
204
+
205
+ Raises:
206
+ HTTPException: If session not found
207
+ """
208
+ if wizard_id not in sessions:
209
+ raise HTTPException(status_code=404, detail="Session not found")
210
+
211
+ session = sessions[wizard_id]
212
+ return {
213
+ "wizard_id": wizard_id,
214
+ "analysis": session["analysis"],
215
+ "result": session["result"],
216
+ {% if 'fix_application' in pattern_ids %}
217
+ "applied_fixes": session.get("applied_fixes", []),
218
+ "modified_code": session.get("modified_code"),
219
+ {% endif %}
220
+ }
221
+
222
+
223
+ # Helper functions
224
+ async def _analyze_code(code: str, context: dict[str, Any]) -> dict[str, Any]:
225
+ """Analyze code (placeholder - implement actual analysis).
226
+
227
+ Args:
228
+ code: Code to analyze
229
+ context: Additional context
230
+
231
+ Returns:
232
+ Analysis results
233
+ """
234
+ # TODO: Implement actual code analysis
235
+ return {
236
+ "lines_of_code": len(code.split("\n")),
237
+ "complexity": "medium",
238
+ "issues_found": 0,
239
+ "context": context,
240
+ }
241
+
242
+
243
+ {% if 'risk_assessment' in pattern_ids %}
244
+ async def _assess_risk(analysis: dict[str, Any]) -> dict[str, Any]:
245
+ """Assess risk based on analysis.
246
+
247
+ Args:
248
+ analysis: Code analysis results
249
+
250
+ Returns:
251
+ Risk assessment
252
+ """
253
+ # TODO: Implement actual risk assessment
254
+ return {
255
+ "alert_level": "LOW",
256
+ "risk_score": 0.2,
257
+ "by_risk_level": {
258
+ "critical": 0,
259
+ "high": 0,
260
+ "medium": 0,
261
+ "low": 0,
262
+ },
263
+ }
264
+ {% endif %}
265
+
266
+
267
+ {% if 'prediction' in pattern_ids %}
268
+ async def _generate_predictions(analysis: dict[str, Any]) -> list[dict[str, Any]]:
269
+ """Generate predictions about future issues.
270
+
271
+ Args:
272
+ analysis: Code analysis results
273
+
274
+ Returns:
275
+ List of predictions
276
+ """
277
+ # TODO: Implement actual predictions
278
+ return [
279
+ {
280
+ "type": "performance",
281
+ "confidence": 0.8,
282
+ "description": "May experience performance issues with large datasets",
283
+ }
284
+ ]
285
+ {% endif %}
286
+
287
+
288
+ {% if 'fix_application' in pattern_ids %}
289
+ async def _suggest_fixes(analysis: dict[str, Any]) -> list[dict[str, Any]]:
290
+ """Suggest fixes for identified issues.
291
+
292
+ Args:
293
+ analysis: Code analysis results
294
+
295
+ Returns:
296
+ List of suggested fixes
297
+ """
298
+ # TODO: Implement actual fix suggestions
299
+ return [
300
+ {
301
+ "id": "fix_1",
302
+ "type": "optimization",
303
+ "description": "Add caching to improve performance",
304
+ "confidence": 0.9,
305
+ }
306
+ ]
307
+
308
+
309
+ async def _apply_fix(code: str, fix: dict[str, Any]) -> str:
310
+ """Apply a fix to code.
311
+
312
+ Args:
313
+ code: Original code
314
+ fix: Fix to apply
315
+
316
+ Returns:
317
+ Modified code
318
+ """
319
+ # TODO: Implement actual fix application
320
+ return code + f"\n# Applied fix: {fix['id']}\n"
321
+ {% endif %}