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,285 @@
1
+ """XML Response Parser
2
+
3
+ Parses structured XML responses from LLMs for dashboard display
4
+ and workflow automation.
5
+
6
+ Copyright 2025 Smart-AI-Memory
7
+ Licensed under Fair Source License 0.9
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import re
13
+ import xml.etree.ElementTree as ET
14
+ from dataclasses import dataclass, field
15
+ from typing import Any
16
+
17
+ import defusedxml.ElementTree as DefusedET
18
+
19
+
20
+ @dataclass
21
+ class Finding:
22
+ """Structured finding from XML response.
23
+
24
+ Represents a single issue, vulnerability, or code review comment
25
+ extracted from an LLM response.
26
+ """
27
+
28
+ severity: str # critical, high, medium, low, info
29
+ title: str
30
+ location: str | None = None
31
+ details: str = ""
32
+ fix: str = ""
33
+
34
+ def to_dict(self) -> dict[str, Any]:
35
+ """Convert to dictionary for serialization."""
36
+ return {
37
+ "severity": self.severity,
38
+ "title": self.title,
39
+ "location": self.location,
40
+ "details": self.details,
41
+ "fix": self.fix,
42
+ }
43
+
44
+ @classmethod
45
+ def from_dict(cls, data: dict[str, Any]) -> Finding:
46
+ """Create Finding from dictionary."""
47
+ return cls(
48
+ severity=data.get("severity", "medium"),
49
+ title=data.get("title", ""),
50
+ location=data.get("location"),
51
+ details=data.get("details", ""),
52
+ fix=data.get("fix", ""),
53
+ )
54
+
55
+
56
+ @dataclass
57
+ class ParsedResponse:
58
+ """Result of parsing an XML response.
59
+
60
+ Contains extracted structured data or fallback raw text
61
+ if parsing fails.
62
+ """
63
+
64
+ success: bool
65
+ raw: str
66
+ summary: str | None = None
67
+ findings: list[Finding] = field(default_factory=list)
68
+ checklist: list[str] = field(default_factory=list)
69
+ errors: list[str] = field(default_factory=list)
70
+ extra: dict[str, Any] = field(default_factory=dict)
71
+
72
+ def to_dict(self) -> dict[str, Any]:
73
+ """Convert to dictionary for serialization."""
74
+ return {
75
+ "success": self.success,
76
+ "raw": self.raw,
77
+ "summary": self.summary,
78
+ "findings": [f.to_dict() for f in self.findings],
79
+ "checklist": self.checklist,
80
+ "errors": self.errors,
81
+ "extra": self.extra,
82
+ }
83
+
84
+ @classmethod
85
+ def from_dict(cls, data: dict[str, Any]) -> ParsedResponse:
86
+ """Create ParsedResponse from dictionary."""
87
+ findings = [Finding.from_dict(f) for f in data.get("findings", [])]
88
+ return cls(
89
+ success=data.get("success", False),
90
+ raw=data.get("raw", ""),
91
+ summary=data.get("summary"),
92
+ findings=findings,
93
+ checklist=data.get("checklist", []),
94
+ errors=data.get("errors", []),
95
+ extra=data.get("extra", {}),
96
+ )
97
+
98
+ @classmethod
99
+ def from_raw(cls, raw: str, errors: list[str] | None = None) -> ParsedResponse:
100
+ """Create a fallback ParsedResponse from raw text."""
101
+ return cls(
102
+ success=False,
103
+ raw=raw,
104
+ summary=raw[:500] if raw else None,
105
+ errors=errors or ["No XML content found"],
106
+ )
107
+
108
+
109
+ class XmlResponseParser:
110
+ """Parse LLM responses containing XML.
111
+
112
+ Extracts structured data from XML-formatted responses while
113
+ gracefully handling malformed or missing XML.
114
+ """
115
+
116
+ def __init__(self, fallback_on_error: bool = True):
117
+ """Initialize the parser.
118
+
119
+ Args:
120
+ fallback_on_error: If True, return raw text on parse failure
121
+ instead of raising an exception.
122
+
123
+ """
124
+ self.fallback_on_error = fallback_on_error
125
+
126
+ def parse(self, response: str) -> ParsedResponse:
127
+ """Parse XML response, with graceful fallback.
128
+
129
+ Args:
130
+ response: The LLM response text, potentially containing XML.
131
+
132
+ Returns:
133
+ ParsedResponse with extracted data or fallback raw text.
134
+
135
+ """
136
+ if not response:
137
+ return ParsedResponse.from_raw("", ["Empty response"])
138
+
139
+ # Extract XML from response (may be wrapped in markdown)
140
+ xml_content = self._extract_xml(response)
141
+
142
+ if not xml_content:
143
+ if self.fallback_on_error:
144
+ return ParsedResponse.from_raw(response, ["No XML content found"])
145
+ raise ValueError("No XML content in response")
146
+
147
+ try:
148
+ # Use defusedxml for safe XML parsing (prevents XXE attacks)
149
+ root = DefusedET.fromstring(xml_content)
150
+
151
+ return ParsedResponse(
152
+ success=True,
153
+ raw=response,
154
+ summary=self._extract_text(root, "summary"),
155
+ findings=self._extract_findings(root),
156
+ checklist=self._extract_checklist(root),
157
+ extra=self._extract_extra(root),
158
+ )
159
+ except ET.ParseError as e:
160
+ if self.fallback_on_error:
161
+ return ParsedResponse.from_raw(response, [f"XML parse error: {e}"])
162
+ raise
163
+
164
+ def _extract_xml(self, response: str) -> str | None:
165
+ """Extract XML content from response.
166
+
167
+ Handles various formats:
168
+ - Direct XML
169
+ - XML in markdown code blocks
170
+ - XML mixed with other text
171
+ """
172
+ # Handle markdown code blocks with xml tag
173
+ xml_block = re.search(r"```xml\s*(.*?)\s*```", response, re.DOTALL)
174
+ if xml_block:
175
+ return xml_block.group(1).strip()
176
+
177
+ # Handle generic markdown code blocks
178
+ code_block = re.search(r"```\s*(.*?)\s*```", response, re.DOTALL)
179
+ if code_block:
180
+ content = code_block.group(1).strip()
181
+ if content.startswith("<"):
182
+ return content
183
+
184
+ # Try to find <response> tags
185
+ response_match = re.search(r"<response\b[^>]*>.*?</response>", response, re.DOTALL)
186
+ if response_match:
187
+ return response_match.group(0)
188
+
189
+ # Try to find any root XML element
190
+ xml_match = re.search(r"<(\w+)\b[^>]*>.*?</\1>", response, re.DOTALL)
191
+ if xml_match:
192
+ return xml_match.group(0)
193
+
194
+ # If response itself looks like XML
195
+ stripped = response.strip()
196
+ if stripped.startswith("<") and stripped.endswith(">"):
197
+ return stripped
198
+
199
+ return None
200
+
201
+ def _extract_text(self, root: ET.Element, tag: str) -> str | None:
202
+ """Extract text content from a tag."""
203
+ element = root.find(f".//{tag}")
204
+ if element is not None and element.text:
205
+ return element.text.strip()
206
+ return None
207
+
208
+ def _extract_findings(self, root: ET.Element) -> list[Finding]:
209
+ """Extract findings from parsed XML."""
210
+ findings = []
211
+
212
+ # Look for findings in various possible locations
213
+ for finding_el in root.findall(".//finding"):
214
+ findings.append(self._parse_finding(finding_el))
215
+
216
+ # Also check for <item> inside <findings>
217
+ findings_container = root.find(".//findings")
218
+ if findings_container is not None:
219
+ for item_el in findings_container.findall("item"):
220
+ findings.append(self._parse_finding(item_el))
221
+
222
+ return findings
223
+
224
+ def _parse_finding(self, element: ET.Element) -> Finding:
225
+ """Parse a single finding element."""
226
+ title = self._extract_text(element, "title") or element.get("title") or ""
227
+ return Finding(
228
+ severity=element.get("severity") or "medium",
229
+ title=title,
230
+ location=self._extract_text(element, "location"),
231
+ details=self._extract_text(element, "details") or "",
232
+ fix=self._extract_text(element, "fix") or "",
233
+ )
234
+
235
+ def _extract_checklist(self, root: ET.Element) -> list[str]:
236
+ """Extract checklist items from parsed XML."""
237
+ items = []
238
+
239
+ # Look for remediation-checklist
240
+ checklist = root.find(".//remediation-checklist")
241
+ if checklist is not None:
242
+ for item in checklist.findall("item"):
243
+ if item.text:
244
+ items.append(item.text.strip())
245
+
246
+ # Also check for generic checklist
247
+ if not items:
248
+ checklist = root.find(".//checklist")
249
+ if checklist is not None:
250
+ for item in checklist.findall("item"):
251
+ if item.text:
252
+ items.append(item.text.strip())
253
+
254
+ return items
255
+
256
+ def _extract_extra(self, root: ET.Element) -> dict[str, Any]:
257
+ """Extract additional fields from the response."""
258
+ extra: dict[str, Any] = {}
259
+
260
+ # Extract verdict (for code review)
261
+ verdict = self._extract_text(root, "verdict")
262
+ if verdict:
263
+ extra["verdict"] = verdict
264
+
265
+ # Extract confidence (for research)
266
+ confidence = root.find(".//confidence")
267
+ if confidence is not None:
268
+ extra["confidence"] = {
269
+ "level": confidence.get("level", "medium"),
270
+ "reasoning": confidence.text.strip() if confidence.text else "",
271
+ }
272
+
273
+ # Extract key insights (for research)
274
+ insights = root.find(".//key-insights")
275
+ if insights is not None:
276
+ extra["key_insights"] = [i.text.strip() for i in insights.findall("insight") if i.text]
277
+
278
+ # Extract suggestions (for code review)
279
+ suggestions = root.find(".//suggestions")
280
+ if suggestions is not None:
281
+ extra["suggestions"] = [
282
+ s.text.strip() for s in suggestions.findall("suggestion") if s.text
283
+ ]
284
+
285
+ return extra
@@ -0,0 +1,313 @@
1
+ """Built-in XML Prompt Templates Registry
2
+
3
+ Provides pre-configured XML templates for common workflows.
4
+
5
+ Copyright 2025 Smart-AI-Memory
6
+ Licensed under Fair Source License 0.9
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from .templates import XmlPromptTemplate
12
+
13
+ # =============================================================================
14
+ # Response Format Definitions
15
+ # =============================================================================
16
+
17
+ SECURITY_AUDIT_RESPONSE = """<response>
18
+ <summary>Brief overall security assessment (1-2 sentences)</summary>
19
+ <findings>
20
+ <finding severity="critical|high|medium|low|info">
21
+ <title>Issue title</title>
22
+ <location>file:line or component</location>
23
+ <details>Description of the vulnerability and potential impact</details>
24
+ <fix>Specific remediation steps with code example if applicable</fix>
25
+ </finding>
26
+ <!-- Additional findings... -->
27
+ </findings>
28
+ <remediation-checklist>
29
+ <item>Priority action item 1</item>
30
+ <item>Priority action item 2</item>
31
+ <!-- Additional items... -->
32
+ </remediation-checklist>
33
+ </response>"""
34
+
35
+ CODE_REVIEW_RESPONSE = """<response>
36
+ <summary>Brief review summary (1-2 sentences)</summary>
37
+ <verdict>approve|approve_with_suggestions|request_changes|reject</verdict>
38
+ <findings>
39
+ <finding severity="critical|high|medium|low|info">
40
+ <title>Issue title</title>
41
+ <location>file:line</location>
42
+ <details>Description of the issue</details>
43
+ <fix>Suggested fix or improvement</fix>
44
+ </finding>
45
+ <!-- Additional findings... -->
46
+ </findings>
47
+ <suggestions>
48
+ <suggestion>Optional improvement suggestion</suggestion>
49
+ <!-- Additional suggestions... -->
50
+ </suggestions>
51
+ <remediation-checklist>
52
+ <item>Required change 1</item>
53
+ <item>Required change 2</item>
54
+ <!-- Additional items if request_changes... -->
55
+ </remediation-checklist>
56
+ </response>"""
57
+
58
+ RESEARCH_RESPONSE = """<response>
59
+ <summary>Research synthesis summary (2-3 sentences)</summary>
60
+ <key-insights>
61
+ <insight>Key insight or finding 1</insight>
62
+ <insight>Key insight or finding 2</insight>
63
+ <!-- Additional insights... -->
64
+ </key-insights>
65
+ <findings>
66
+ <finding severity="info">
67
+ <title>Topic or concept</title>
68
+ <details>Explanation with context</details>
69
+ </finding>
70
+ <!-- Additional topics if needed... -->
71
+ </findings>
72
+ <confidence level="high|medium|low">Reasoning for confidence level</confidence>
73
+ <remediation-checklist>
74
+ <item>Recommended next step 1</item>
75
+ <item>Recommended next step 2</item>
76
+ </remediation-checklist>
77
+ </response>"""
78
+
79
+ BUG_ANALYSIS_RESPONSE = """<response>
80
+ <summary>Root cause summary (1-2 sentences)</summary>
81
+ <findings>
82
+ <finding severity="critical|high|medium|low">
83
+ <title>Bug description</title>
84
+ <location>file:line where issue originates</location>
85
+ <details>Root cause analysis</details>
86
+ <fix>Recommended fix with code</fix>
87
+ </finding>
88
+ </findings>
89
+ <remediation-checklist>
90
+ <item>Fix step 1</item>
91
+ <item>Verification step</item>
92
+ <item>Test to add</item>
93
+ </remediation-checklist>
94
+ </response>"""
95
+
96
+ PERF_AUDIT_RESPONSE = """<response>
97
+ <summary>Performance assessment summary (1-2 sentences)</summary>
98
+ <performance-score>0-100</performance-score>
99
+ <findings>
100
+ <finding severity="critical|high|medium|low">
101
+ <title>Performance issue title</title>
102
+ <location>file:line or component</location>
103
+ <details>Description of the bottleneck and its impact</details>
104
+ <fix>Optimization recommendation with code example</fix>
105
+ </finding>
106
+ </findings>
107
+ <remediation-checklist>
108
+ <item>Optimization priority 1</item>
109
+ <item>Optimization priority 2</item>
110
+ </remediation-checklist>
111
+ </response>"""
112
+
113
+ REFACTOR_PLAN_RESPONSE = """<response>
114
+ <summary>Tech debt assessment (1-2 sentences)</summary>
115
+ <trajectory>increasing|stable|decreasing</trajectory>
116
+ <findings>
117
+ <finding severity="high|medium|low">
118
+ <title>Debt item description</title>
119
+ <location>file:line</location>
120
+ <details>Impact and complexity assessment</details>
121
+ <fix>Refactoring approach</fix>
122
+ </finding>
123
+ </findings>
124
+ <roadmap>
125
+ <phase priority="1|2|3">
126
+ <name>Phase name</name>
127
+ <description>What to accomplish</description>
128
+ <effort>high|medium|low</effort>
129
+ </phase>
130
+ </roadmap>
131
+ <remediation-checklist>
132
+ <item>Immediate action 1</item>
133
+ <item>Immediate action 2</item>
134
+ </remediation-checklist>
135
+ </response>"""
136
+
137
+ TEST_GEN_RESPONSE = """<response>
138
+ <summary>Test generation summary (1-2 sentences)</summary>
139
+ <coverage-improvement>Estimated coverage improvement</coverage-improvement>
140
+ <findings>
141
+ <finding severity="info">
142
+ <title>Untested area</title>
143
+ <location>file:function or class</location>
144
+ <details>Why this needs testing</details>
145
+ <fix>Test approach recommendation</fix>
146
+ </finding>
147
+ </findings>
148
+ <tests>
149
+ <test target="function or class name">
150
+ <type>unit|integration|edge-case</type>
151
+ <description>What this test verifies</description>
152
+ <code><![CDATA[
153
+ def test_example():
154
+ # Test code here
155
+ pass
156
+ ]]></code>
157
+ </test>
158
+ </tests>
159
+ <remediation-checklist>
160
+ <item>Test to add first</item>
161
+ <item>Test to add second</item>
162
+ </remediation-checklist>
163
+ </response>"""
164
+
165
+ DOC_GEN_RESPONSE = """<response>
166
+ <summary>Documentation summary (1-2 sentences)</summary>
167
+ <sections>
168
+ <section name="Section Title">
169
+ <content>Section content in markdown</content>
170
+ </section>
171
+ </sections>
172
+ <findings>
173
+ <finding severity="info">
174
+ <title>Documentation gap or improvement</title>
175
+ <details>What needs documentation</details>
176
+ </finding>
177
+ </findings>
178
+ <remediation-checklist>
179
+ <item>Documentation improvement 1</item>
180
+ <item>Documentation improvement 2</item>
181
+ </remediation-checklist>
182
+ </response>"""
183
+
184
+ RELEASE_PREP_RESPONSE = """<response>
185
+ <summary>Release readiness assessment (1-2 sentences)</summary>
186
+ <verdict>approved|blocked|needs-review</verdict>
187
+ <confidence>high|medium|low</confidence>
188
+ <findings>
189
+ <finding severity="blocker|warning|info">
190
+ <title>Issue title</title>
191
+ <location>Component or area</location>
192
+ <details>Description of the issue</details>
193
+ <fix>Required action before release</fix>
194
+ </finding>
195
+ </findings>
196
+ <checklist>
197
+ <item status="pass|fail|skip">Check description</item>
198
+ </checklist>
199
+ <remediation-checklist>
200
+ <item>Pre-release action 1</item>
201
+ <item>Pre-release action 2</item>
202
+ </remediation-checklist>
203
+ </response>"""
204
+
205
+ DEPENDENCY_CHECK_RESPONSE = """<response>
206
+ <summary>Dependency security assessment (1-2 sentences)</summary>
207
+ <risk-level>critical|high|medium|low</risk-level>
208
+ <risk-score>0-100</risk-score>
209
+ <findings>
210
+ <finding severity="critical|high|medium|low">
211
+ <title>Vulnerability or issue</title>
212
+ <location>package@version</location>
213
+ <details>CVE or issue description</details>
214
+ <fix>Upgrade or mitigation recommendation</fix>
215
+ </finding>
216
+ </findings>
217
+ <remediation-checklist>
218
+ <item>Upgrade package X to version Y</item>
219
+ <item>Review dependency Z</item>
220
+ </remediation-checklist>
221
+ </response>"""
222
+
223
+
224
+ # =============================================================================
225
+ # Built-in Templates
226
+ # =============================================================================
227
+
228
+ BUILTIN_TEMPLATES: dict[str, XmlPromptTemplate] = {
229
+ "security-audit": XmlPromptTemplate(
230
+ name="security-audit",
231
+ schema_version="1.0",
232
+ response_format=SECURITY_AUDIT_RESPONSE,
233
+ ),
234
+ "code-review": XmlPromptTemplate(
235
+ name="code-review",
236
+ schema_version="1.0",
237
+ response_format=CODE_REVIEW_RESPONSE,
238
+ ),
239
+ "research": XmlPromptTemplate(
240
+ name="research",
241
+ schema_version="1.0",
242
+ response_format=RESEARCH_RESPONSE,
243
+ ),
244
+ "bug-analysis": XmlPromptTemplate(
245
+ name="bug-analysis",
246
+ schema_version="1.0",
247
+ response_format=BUG_ANALYSIS_RESPONSE,
248
+ ),
249
+ "perf-audit": XmlPromptTemplate(
250
+ name="perf-audit",
251
+ schema_version="1.0",
252
+ response_format=PERF_AUDIT_RESPONSE,
253
+ ),
254
+ "refactor-plan": XmlPromptTemplate(
255
+ name="refactor-plan",
256
+ schema_version="1.0",
257
+ response_format=REFACTOR_PLAN_RESPONSE,
258
+ ),
259
+ "test-gen": XmlPromptTemplate(
260
+ name="test-gen",
261
+ schema_version="1.0",
262
+ response_format=TEST_GEN_RESPONSE,
263
+ ),
264
+ "doc-gen": XmlPromptTemplate(
265
+ name="doc-gen",
266
+ schema_version="1.0",
267
+ response_format=DOC_GEN_RESPONSE,
268
+ ),
269
+ "release-prep": XmlPromptTemplate(
270
+ name="release-prep",
271
+ schema_version="1.0",
272
+ response_format=RELEASE_PREP_RESPONSE,
273
+ ),
274
+ "dependency-check": XmlPromptTemplate(
275
+ name="dependency-check",
276
+ schema_version="1.0",
277
+ response_format=DEPENDENCY_CHECK_RESPONSE,
278
+ ),
279
+ }
280
+
281
+
282
+ def get_template(name: str) -> XmlPromptTemplate | None:
283
+ """Get a built-in template by name.
284
+
285
+ Args:
286
+ name: Template name (e.g., "security-audit", "code-review").
287
+
288
+ Returns:
289
+ XmlPromptTemplate if found, None otherwise.
290
+
291
+ """
292
+ return BUILTIN_TEMPLATES.get(name)
293
+
294
+
295
+ def list_templates() -> list[str]:
296
+ """List all available built-in template names.
297
+
298
+ Returns:
299
+ List of template names.
300
+
301
+ """
302
+ return list(BUILTIN_TEMPLATES.keys())
303
+
304
+
305
+ def register_template(name: str, template: XmlPromptTemplate) -> None:
306
+ """Register a custom template.
307
+
308
+ Args:
309
+ name: Template name for lookup.
310
+ template: XmlPromptTemplate instance.
311
+
312
+ """
313
+ BUILTIN_TEMPLATES[name] = template