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,423 @@
1
+ """Wizard-to-Agent Bridge Adapter
2
+
3
+ Bridges existing wizards to the Agent Factory interface, allowing
4
+ wizards to be used in Agent Factory workflows and pipelines.
5
+
6
+ This enables:
7
+ - Using existing wizards in Agent Factory workflows
8
+ - Combining wizards with other agents
9
+ - Applying model tier routing to wizard operations
10
+ - Cost tracking for wizard calls
11
+
12
+ Copyright 2025 Smart-AI-Memory
13
+ Licensed under Fair Source License 0.9
14
+ """
15
+
16
+ import logging
17
+
18
+ from attune_llm.agent_factory.base import (
19
+ AgentConfig,
20
+ AgentRole,
21
+ BaseAdapter,
22
+ BaseAgent,
23
+ BaseWorkflow,
24
+ WorkflowConfig,
25
+ )
26
+ from attune_llm.agent_factory.decorators import log_performance, safe_agent_operation
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ class WizardAgent(BaseAgent):
32
+ """Agent wrapper for existing wizards.
33
+
34
+ Adapts the wizard's analyze() method to the Agent Factory
35
+ invoke() interface.
36
+ """
37
+
38
+ def __init__(self, wizard, config: AgentConfig):
39
+ """Initialize wizard agent.
40
+
41
+ Args:
42
+ wizard: Wizard instance (must have analyze() method)
43
+ config: Agent configuration
44
+
45
+ """
46
+ super().__init__(config)
47
+ self._wizard = wizard
48
+
49
+ # Extract wizard properties
50
+ self._wizard_name = getattr(wizard, "name", wizard.__class__.__name__)
51
+ self._wizard_level = getattr(wizard, "level", 4)
52
+
53
+ @property
54
+ def wizard(self):
55
+ """Get the underlying wizard."""
56
+ return self._wizard
57
+
58
+ @property
59
+ def wizard_level(self) -> int:
60
+ """Get the wizard's empathy level."""
61
+ return self._wizard_level
62
+
63
+ @safe_agent_operation("wizard_invoke")
64
+ @log_performance(threshold_seconds=5.0)
65
+ async def invoke(self, input_data: str | dict, context: dict | None = None) -> dict:
66
+ """Invoke the wizard.
67
+
68
+ Transforms input to wizard format, calls analyze(),
69
+ and transforms output to Agent Factory format.
70
+
71
+ Args:
72
+ input_data: String query or dict with input
73
+ context: Optional additional context
74
+
75
+ Returns:
76
+ Dict with output, metadata, predictions, recommendations
77
+
78
+ """
79
+ # Build wizard context
80
+ wizard_context = context.copy() if context else {}
81
+
82
+ if isinstance(input_data, str):
83
+ wizard_context["input"] = input_data
84
+ wizard_context["query"] = input_data
85
+ else:
86
+ wizard_context.update(input_data)
87
+
88
+ # Add agent metadata
89
+ wizard_context["agent_name"] = self.name
90
+ wizard_context["agent_role"] = self.role.value
91
+
92
+ # Add conversation history if available
93
+ if self._conversation_history:
94
+ wizard_context["conversation_history"] = self._conversation_history[-10:]
95
+
96
+ # Call wizard analyze
97
+ result = await self._wizard.analyze(wizard_context)
98
+
99
+ # Transform to Agent Factory format
100
+ output = self._extract_output(result)
101
+
102
+ # Track conversation
103
+ user_input = wizard_context.get("input", wizard_context.get("query", str(input_data)))
104
+ self._conversation_history.append({"role": "user", "content": user_input})
105
+ self._conversation_history.append({"role": "assistant", "content": str(output)})
106
+
107
+ return {
108
+ "output": output,
109
+ "metadata": {
110
+ "wizard": self._wizard_name,
111
+ "level": self._wizard_level,
112
+ "confidence": result.get("confidence", 0.0),
113
+ "from_cache": result.get("_from_cache", False),
114
+ "model": self.model,
115
+ },
116
+ "predictions": result.get("predictions", []),
117
+ "recommendations": result.get("recommendations", []),
118
+ "patterns": result.get("patterns", []),
119
+ "raw_result": result,
120
+ }
121
+
122
+ def _extract_output(self, result: dict) -> str:
123
+ """Extract the main output from wizard result.
124
+
125
+ Wizards return various formats, so we need to normalize.
126
+ """
127
+ # Try common output keys
128
+ for key in ["output", "response", "result", "analysis", "summary"]:
129
+ if result.get(key):
130
+ value = result[key]
131
+ if isinstance(value, str):
132
+ return value
133
+ if isinstance(value, list):
134
+ return "\n".join(str(item) for item in value)
135
+ return str(value)
136
+
137
+ # Fall back to recommendations
138
+ if "recommendations" in result:
139
+ recs = result["recommendations"]
140
+ if isinstance(recs, list):
141
+ return "\n".join(f"- {r}" for r in recs)
142
+
143
+ # Last resort: stringify the result
144
+ return str(result)
145
+
146
+ async def stream(self, input_data: str | dict, context: dict | None = None):
147
+ """Stream wizard response.
148
+
149
+ Most wizards don't support streaming, so we yield the full response.
150
+ """
151
+ result = await self.invoke(input_data, context)
152
+ yield result
153
+
154
+
155
+ class WizardWorkflow(BaseWorkflow):
156
+ """Workflow for chaining multiple wizards.
157
+
158
+ Allows wizards to be composed into pipelines where
159
+ the output of one feeds into the next.
160
+ """
161
+
162
+ async def run(self, input_data: str | dict, initial_state: dict | None = None) -> dict:
163
+ """Run the wizard workflow.
164
+
165
+ Args:
166
+ input_data: Initial input
167
+ initial_state: Optional starting state
168
+
169
+ Returns:
170
+ Combined results from all wizards
171
+
172
+ """
173
+ self._state = initial_state or {}
174
+ self._state["input"] = input_data
175
+
176
+ results: list[dict] = []
177
+ current_input = input_data
178
+
179
+ for agent in self.agents.values():
180
+ # Build context with previous results
181
+ context = {
182
+ "previous_results": results,
183
+ "state": self._state,
184
+ }
185
+
186
+ # Invoke wizard agent
187
+ result = await agent.invoke(current_input, context)
188
+ result["agent"] = agent.name
189
+ results.append(result)
190
+
191
+ # Pass output to next wizard
192
+ current_input = result.get("output", "")
193
+
194
+ # Collect predictions and recommendations
195
+ self._state.setdefault("all_predictions", []).extend(result.get("predictions", []))
196
+ self._state.setdefault("all_recommendations", []).extend(
197
+ result.get("recommendations", []),
198
+ )
199
+
200
+ # Build final output
201
+ self._state["results"] = results
202
+ self._state["final_output"] = results[-1]["output"] if results else ""
203
+
204
+ return {
205
+ "output": self._state["final_output"],
206
+ "results": results,
207
+ "state": self._state,
208
+ "agents_invoked": [r.get("agent") for r in results],
209
+ "all_predictions": self._state.get("all_predictions", []),
210
+ "all_recommendations": self._state.get("all_recommendations", []),
211
+ }
212
+
213
+ async def stream(self, input_data: str | dict, initial_state: dict | None = None):
214
+ """Stream workflow execution."""
215
+ self._state = initial_state or {}
216
+ self._state["input"] = input_data
217
+
218
+ for agent in self.agents.values():
219
+ context = {"state": self._state}
220
+ yield {"event": "wizard_start", "wizard": agent.name}
221
+
222
+ # agent.stream returns an async generator
223
+ stream_gen = agent.stream(input_data, context)
224
+ async for chunk in stream_gen: # type: ignore[attr-defined]
225
+ yield {"event": "wizard_output", "wizard": agent.name, "data": chunk}
226
+
227
+ yield {"event": "wizard_end", "wizard": agent.name}
228
+
229
+
230
+ class WizardAdapter(BaseAdapter):
231
+ """Adapter for integrating wizards with Agent Factory.
232
+
233
+ Allows existing wizards to be used as agents in the
234
+ Agent Factory ecosystem.
235
+
236
+ Example:
237
+ adapter = WizardAdapter()
238
+
239
+ # Wrap a wizard instance
240
+ wizard = MyCustomWizard()
241
+ agent = adapter.create_agent_from_wizard(
242
+ wizard,
243
+ name="my_wizard",
244
+ model_tier="capable"
245
+ )
246
+
247
+ # Use in workflow
248
+ result = await agent.invoke({"input": data})
249
+
250
+ """
251
+
252
+ def __init__(self, provider: str = "anthropic", api_key: str | None = None):
253
+ """Initialize wizard adapter.
254
+
255
+ Args:
256
+ provider: LLM provider (for model tier resolution)
257
+ api_key: API key (uses env var if not provided)
258
+
259
+ """
260
+ self.provider = provider
261
+ self.api_key = api_key
262
+
263
+ @property
264
+ def framework_name(self) -> str:
265
+ return "wizard"
266
+
267
+ def is_available(self) -> bool:
268
+ """Wizard adapter is always available."""
269
+ return True
270
+
271
+ def create_agent(self, config: AgentConfig) -> WizardAgent:
272
+ """Create a wizard agent from config.
273
+
274
+ Note: This requires a wizard instance in config.framework_options.
275
+
276
+ Args:
277
+ config: Agent configuration with wizard in framework_options
278
+
279
+ Returns:
280
+ WizardAgent instance
281
+
282
+ """
283
+ wizard = config.framework_options.get("wizard")
284
+ if wizard is None:
285
+ raise ValueError(
286
+ "Wizard instance required in config.framework_options['wizard']. "
287
+ "Use create_agent_from_wizard() for easier wizard wrapping.",
288
+ )
289
+
290
+ return WizardAgent(wizard, config)
291
+
292
+ def create_agent_from_wizard(
293
+ self,
294
+ wizard,
295
+ name: str | None = None,
296
+ role: AgentRole | str = AgentRole.CUSTOM,
297
+ model_tier: str = "capable",
298
+ **kwargs,
299
+ ) -> WizardAgent:
300
+ """Create an agent from a wizard instance.
301
+
302
+ This is the preferred method for wrapping wizards.
303
+
304
+ Args:
305
+ wizard: Wizard instance
306
+ name: Agent name (defaults to wizard name)
307
+ role: Agent role
308
+ model_tier: Model tier for LLM calls
309
+ **kwargs: Additional AgentConfig options
310
+
311
+ Returns:
312
+ WizardAgent wrapping the wizard
313
+
314
+ """
315
+ # Get wizard name
316
+ wizard_name = getattr(wizard, "name", wizard.__class__.__name__)
317
+ agent_name = name or wizard_name.lower().replace(" ", "_")
318
+
319
+ # Get wizard empathy level
320
+ wizard_level = getattr(wizard, "level", 4)
321
+
322
+ # Parse role
323
+ if isinstance(role, str):
324
+ try:
325
+ role = AgentRole(role.lower())
326
+ except ValueError:
327
+ role = AgentRole.CUSTOM
328
+
329
+ # Build config
330
+ config = AgentConfig(
331
+ name=agent_name,
332
+ role=role,
333
+ description=f"Agent wrapping {wizard_name}",
334
+ model_tier=model_tier,
335
+ empathy_level=wizard_level,
336
+ framework_options={"wizard": wizard},
337
+ **kwargs,
338
+ )
339
+
340
+ return WizardAgent(wizard, config)
341
+
342
+ def create_agent_from_wizard_class(
343
+ self,
344
+ wizard_class: type,
345
+ name: str | None = None,
346
+ wizard_kwargs: dict | None = None,
347
+ **agent_kwargs,
348
+ ) -> WizardAgent:
349
+ """Create an agent from a wizard class.
350
+
351
+ Instantiates the wizard and wraps it.
352
+
353
+ Args:
354
+ wizard_class: Wizard class to instantiate
355
+ name: Agent name
356
+ wizard_kwargs: Arguments for wizard constructor
357
+ **agent_kwargs: Arguments for create_agent_from_wizard
358
+
359
+ Returns:
360
+ WizardAgent instance
361
+
362
+ """
363
+ wizard_kwargs = wizard_kwargs or {}
364
+ wizard = wizard_class(**wizard_kwargs)
365
+
366
+ return self.create_agent_from_wizard(wizard, name=name, **agent_kwargs)
367
+
368
+ def create_workflow(self, config: WorkflowConfig, agents: list[BaseAgent]) -> WizardWorkflow:
369
+ """Create a workflow from wizard agents.
370
+
371
+ Args:
372
+ config: Workflow configuration
373
+ agents: List of wizard agents
374
+
375
+ Returns:
376
+ WizardWorkflow instance
377
+
378
+ """
379
+ return WizardWorkflow(config, agents)
380
+
381
+ def create_tool(
382
+ self,
383
+ name: str,
384
+ description: str,
385
+ func,
386
+ args_schema: dict | None = None,
387
+ ) -> dict:
388
+ """Create a tool dict (wizards don't use tools directly).
389
+
390
+ Returns a tool dict for documentation purposes.
391
+ """
392
+ return {
393
+ "name": name,
394
+ "description": description,
395
+ "func": func,
396
+ "args_schema": args_schema,
397
+ "note": "Wizards typically don't use external tools",
398
+ }
399
+
400
+
401
+ # Convenience function for quick wizard wrapping
402
+ def wrap_wizard(wizard, name: str | None = None, model_tier: str = "capable") -> WizardAgent:
403
+ """Quick helper to wrap a wizard as an agent.
404
+
405
+ Args:
406
+ wizard: Wizard instance
407
+ name: Optional agent name
408
+ model_tier: Model tier
409
+
410
+ Returns:
411
+ WizardAgent instance
412
+
413
+ Example:
414
+ from attune_llm.agent_factory.adapters.wizard_adapter import wrap_wizard
415
+
416
+ my_wizard = MyCustomWizard()
417
+ agent = wrap_wizard(my_wizard, model_tier="capable")
418
+
419
+ result = await agent.invoke({"input": data})
420
+
421
+ """
422
+ adapter = WizardAdapter()
423
+ return adapter.create_agent_from_wizard(wizard, name=name, model_tier=model_tier)