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,732 @@
1
+ """Agent and Workflow Generator
2
+
3
+ Generates concrete agents and workflows from blueprints.
4
+
5
+ This module transforms abstract blueprints (from Socratic questioning)
6
+ into runnable agent instances and workflow configurations.
7
+
8
+ Copyright 2026 Smart-AI-Memory
9
+ Licensed under Fair Source License 0.9
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ from dataclasses import dataclass, field
16
+ from datetime import datetime
17
+ from typing import TYPE_CHECKING, Any
18
+
19
+ from .blueprint import (
20
+ AgentBlueprint,
21
+ AgentRole,
22
+ AgentSpec,
23
+ StageSpec,
24
+ ToolCategory,
25
+ ToolSpec,
26
+ WorkflowBlueprint,
27
+ )
28
+ from .success import SuccessCriteria
29
+
30
+ if TYPE_CHECKING:
31
+ from ..workflows.xml_enhanced_crew import XMLAgent
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+
36
+ # =============================================================================
37
+ # AGENT TEMPLATES
38
+ # =============================================================================
39
+
40
+
41
+ @dataclass
42
+ class AgentTemplate:
43
+ """Template for generating specialized agents.
44
+
45
+ Templates provide pre-configured agent specifications that can be
46
+ customized based on Socratic questioning results.
47
+ """
48
+
49
+ id: str
50
+ name: str
51
+ role: AgentRole
52
+ base_goal: str
53
+ base_backstory: str
54
+ default_tools: list[str]
55
+ quality_focus: list[str]
56
+ languages: list[str] # Empty = all languages
57
+ model_tier: str = "capable"
58
+ custom_instructions: list[str] = field(default_factory=list)
59
+
60
+ def create_spec(
61
+ self,
62
+ customizations: dict[str, Any] | None = None,
63
+ ) -> AgentSpec:
64
+ """Create an AgentSpec from this template.
65
+
66
+ Args:
67
+ customizations: Override template defaults
68
+
69
+ Returns:
70
+ AgentSpec with customizations applied
71
+ """
72
+ customizations = customizations or {}
73
+
74
+ # Build goal with customizations
75
+ goal = customizations.get("goal", self.base_goal)
76
+ if "goal_suffix" in customizations:
77
+ goal = f"{goal} {customizations['goal_suffix']}"
78
+
79
+ # Build backstory with customizations
80
+ backstory = customizations.get("backstory", self.base_backstory)
81
+ if "expertise" in customizations:
82
+ backstory = f"{backstory} Specialized in: {', '.join(customizations['expertise'])}."
83
+
84
+ # Merge languages
85
+ languages = customizations.get("languages", self.languages)
86
+
87
+ # Merge quality focus
88
+ quality = list(self.quality_focus)
89
+ if "quality_focus" in customizations:
90
+ quality.extend(customizations["quality_focus"])
91
+ quality = list(dict.fromkeys(quality)) # Dedupe preserving order
92
+
93
+ # Build tools
94
+ tools = self._build_tools(customizations.get("tools", []))
95
+
96
+ return AgentSpec(
97
+ id=customizations.get("id", self.id),
98
+ name=customizations.get("name", self.name),
99
+ role=self.role,
100
+ goal=goal,
101
+ backstory=backstory,
102
+ tools=tools,
103
+ quality_focus=quality,
104
+ model_tier=customizations.get("model_tier", self.model_tier),
105
+ custom_instructions=self.custom_instructions + customizations.get("instructions", []),
106
+ languages=languages,
107
+ )
108
+
109
+ def _build_tools(self, additional_tools: list[str]) -> list[ToolSpec]:
110
+ """Build tool specifications."""
111
+ tools = []
112
+ all_tool_ids = list(dict.fromkeys(self.default_tools + additional_tools))
113
+
114
+ for tool_id in all_tool_ids:
115
+ tool_spec = TOOL_REGISTRY.get(tool_id)
116
+ if tool_spec:
117
+ tools.append(tool_spec)
118
+
119
+ return tools
120
+
121
+
122
+ # =============================================================================
123
+ # TOOL REGISTRY
124
+ # =============================================================================
125
+
126
+
127
+ TOOL_REGISTRY: dict[str, ToolSpec] = {
128
+ "grep_code": ToolSpec(
129
+ id="grep_code",
130
+ name="Code Search",
131
+ category=ToolCategory.CODE_SEARCH,
132
+ description="Search codebase for patterns using regex",
133
+ parameters={
134
+ "pattern": {"type": "string", "required": True},
135
+ "file_glob": {"type": "string", "required": False},
136
+ "case_sensitive": {"type": "boolean", "default": False},
137
+ },
138
+ ),
139
+ "read_file": ToolSpec(
140
+ id="read_file",
141
+ name="Read File",
142
+ category=ToolCategory.CODE_ANALYSIS,
143
+ description="Read file contents",
144
+ parameters={
145
+ "path": {"type": "string", "required": True},
146
+ "start_line": {"type": "integer", "required": False},
147
+ "end_line": {"type": "integer", "required": False},
148
+ },
149
+ ),
150
+ "analyze_ast": ToolSpec(
151
+ id="analyze_ast",
152
+ name="AST Analysis",
153
+ category=ToolCategory.CODE_ANALYSIS,
154
+ description="Parse and analyze code abstract syntax tree",
155
+ parameters={
156
+ "code": {"type": "string", "required": True},
157
+ "language": {"type": "string", "required": True},
158
+ },
159
+ ),
160
+ "security_scan": ToolSpec(
161
+ id="security_scan",
162
+ name="Security Scanner",
163
+ category=ToolCategory.SECURITY,
164
+ description="Run security vulnerability scanner",
165
+ parameters={
166
+ "path": {"type": "string", "required": True},
167
+ "rules": {"type": "array", "required": False},
168
+ },
169
+ cost_tier="moderate",
170
+ ),
171
+ "run_linter": ToolSpec(
172
+ id="run_linter",
173
+ name="Run Linter",
174
+ category=ToolCategory.LINTING,
175
+ description="Run code linter and return issues",
176
+ parameters={
177
+ "path": {"type": "string", "required": True},
178
+ "config": {"type": "string", "required": False},
179
+ },
180
+ ),
181
+ "run_tests": ToolSpec(
182
+ id="run_tests",
183
+ name="Run Tests",
184
+ category=ToolCategory.TESTING,
185
+ description="Execute test suite and return results",
186
+ parameters={
187
+ "path": {"type": "string", "required": False},
188
+ "coverage": {"type": "boolean", "default": True},
189
+ },
190
+ cost_tier="moderate",
191
+ ),
192
+ "edit_file": ToolSpec(
193
+ id="edit_file",
194
+ name="Edit File",
195
+ category=ToolCategory.CODE_MODIFICATION,
196
+ description="Make targeted edits to a file",
197
+ parameters={
198
+ "path": {"type": "string", "required": True},
199
+ "old_text": {"type": "string", "required": True},
200
+ "new_text": {"type": "string", "required": True},
201
+ },
202
+ is_mutating=True,
203
+ requires_confirmation=True,
204
+ ),
205
+ "query_patterns": ToolSpec(
206
+ id="query_patterns",
207
+ name="Query Pattern Library",
208
+ category=ToolCategory.KNOWLEDGE,
209
+ description="Search learned patterns for similar issues",
210
+ parameters={
211
+ "query": {"type": "string", "required": True},
212
+ "limit": {"type": "integer", "default": 5},
213
+ },
214
+ ),
215
+ "complexity_analysis": ToolSpec(
216
+ id="complexity_analysis",
217
+ name="Complexity Analysis",
218
+ category=ToolCategory.CODE_ANALYSIS,
219
+ description="Calculate code complexity metrics",
220
+ parameters={
221
+ "path": {"type": "string", "required": True},
222
+ },
223
+ ),
224
+ }
225
+
226
+
227
+ # =============================================================================
228
+ # AGENT TEMPLATE REGISTRY
229
+ # =============================================================================
230
+
231
+
232
+ AGENT_TEMPLATES: dict[str, AgentTemplate] = {
233
+ "security_reviewer": AgentTemplate(
234
+ id="security_reviewer",
235
+ name="Security Reviewer",
236
+ role=AgentRole.AUDITOR,
237
+ base_goal="Identify security vulnerabilities and recommend mitigations",
238
+ base_backstory=(
239
+ "Expert security analyst with deep knowledge of OWASP Top 10, "
240
+ "secure coding practices, and common vulnerability patterns."
241
+ ),
242
+ default_tools=["grep_code", "read_file", "security_scan", "query_patterns"],
243
+ quality_focus=["security"],
244
+ languages=[],
245
+ model_tier="capable",
246
+ custom_instructions=[
247
+ "Prioritize critical and high severity issues",
248
+ "Provide specific code locations for each finding",
249
+ "Include remediation recommendations",
250
+ ],
251
+ ),
252
+ "code_quality_reviewer": AgentTemplate(
253
+ id="code_quality_reviewer",
254
+ name="Code Quality Reviewer",
255
+ role=AgentRole.REVIEWER,
256
+ base_goal="Assess code quality, maintainability, and adherence to best practices",
257
+ base_backstory=(
258
+ "Experienced code reviewer with expertise in clean code principles, "
259
+ "design patterns, and maintainability best practices."
260
+ ),
261
+ default_tools=["grep_code", "read_file", "run_linter", "complexity_analysis"],
262
+ quality_focus=["maintainability", "reliability"],
263
+ languages=[],
264
+ model_tier="capable",
265
+ ),
266
+ "performance_analyzer": AgentTemplate(
267
+ id="performance_analyzer",
268
+ name="Performance Analyzer",
269
+ role=AgentRole.ANALYZER,
270
+ base_goal="Identify performance bottlenecks and optimization opportunities",
271
+ base_backstory=(
272
+ "Performance optimization specialist with expertise in algorithmic "
273
+ "complexity, memory management, and scalability patterns."
274
+ ),
275
+ default_tools=["grep_code", "read_file", "complexity_analysis", "analyze_ast"],
276
+ quality_focus=["performance"],
277
+ languages=[],
278
+ model_tier="capable",
279
+ ),
280
+ "test_generator": AgentTemplate(
281
+ id="test_generator",
282
+ name="Test Generator",
283
+ role=AgentRole.GENERATOR,
284
+ base_goal="Generate comprehensive test cases for untested code",
285
+ base_backstory=(
286
+ "Testing expert skilled in unit testing, integration testing, "
287
+ "and test-driven development methodologies."
288
+ ),
289
+ default_tools=["read_file", "analyze_ast", "run_tests", "edit_file"],
290
+ quality_focus=["testability", "reliability"],
291
+ languages=[],
292
+ model_tier="capable",
293
+ custom_instructions=[
294
+ "Generate both happy path and edge case tests",
295
+ "Follow the existing test patterns in the codebase",
296
+ "Ensure tests are deterministic and isolated",
297
+ ],
298
+ ),
299
+ "documentation_writer": AgentTemplate(
300
+ id="documentation_writer",
301
+ name="Documentation Writer",
302
+ role=AgentRole.GENERATOR,
303
+ base_goal="Generate clear, comprehensive documentation",
304
+ base_backstory=(
305
+ "Technical writer with expertise in API documentation, "
306
+ "code comments, and developer guides."
307
+ ),
308
+ default_tools=["read_file", "analyze_ast", "grep_code"],
309
+ quality_focus=["maintainability"],
310
+ languages=[],
311
+ model_tier="cheap",
312
+ ),
313
+ "style_enforcer": AgentTemplate(
314
+ id="style_enforcer",
315
+ name="Style Enforcer",
316
+ role=AgentRole.REVIEWER,
317
+ base_goal="Ensure code follows team style guidelines",
318
+ base_backstory=(
319
+ "Code style expert with knowledge of language-specific "
320
+ "conventions and formatting standards."
321
+ ),
322
+ default_tools=["run_linter", "read_file"],
323
+ quality_focus=["maintainability"],
324
+ languages=[],
325
+ model_tier="cheap",
326
+ ),
327
+ "result_synthesizer": AgentTemplate(
328
+ id="result_synthesizer",
329
+ name="Result Synthesizer",
330
+ role=AgentRole.REPORTER,
331
+ base_goal="Synthesize findings into clear, actionable reports",
332
+ base_backstory=(
333
+ "Technical communicator skilled at translating complex "
334
+ "findings into understandable recommendations."
335
+ ),
336
+ default_tools=["query_patterns"],
337
+ quality_focus=[],
338
+ languages=[],
339
+ model_tier="cheap",
340
+ ),
341
+ }
342
+
343
+
344
+ # =============================================================================
345
+ # AGENT GENERATOR
346
+ # =============================================================================
347
+
348
+
349
+ class AgentGenerator:
350
+ """Generates agents and workflows from blueprints.
351
+
352
+ Example:
353
+ >>> generator = AgentGenerator()
354
+ >>>
355
+ >>> # Generate from blueprint
356
+ >>> blueprint = WorkflowBlueprint(...)
357
+ >>> workflow = generator.generate_workflow(blueprint)
358
+ >>>
359
+ >>> # Generate from template
360
+ >>> agent = generator.generate_agent_from_template(
361
+ ... "security_reviewer",
362
+ ... customizations={"languages": ["python"]}
363
+ ... )
364
+ """
365
+
366
+ def __init__(self):
367
+ """Initialize the generator."""
368
+ self.templates = AGENT_TEMPLATES.copy()
369
+ self.tools = TOOL_REGISTRY.copy()
370
+
371
+ def register_template(self, template: AgentTemplate) -> None:
372
+ """Register a custom agent template."""
373
+ self.templates[template.id] = template
374
+
375
+ def register_tool(self, tool: ToolSpec) -> None:
376
+ """Register a custom tool."""
377
+ self.tools[tool.id] = tool
378
+
379
+ def generate_agent_from_template(
380
+ self,
381
+ template_id: str,
382
+ customizations: dict[str, Any] | None = None,
383
+ ) -> AgentBlueprint:
384
+ """Generate an agent blueprint from a template.
385
+
386
+ Args:
387
+ template_id: ID of the template to use
388
+ customizations: Override template defaults
389
+
390
+ Returns:
391
+ AgentBlueprint ready for instantiation
392
+
393
+ Raises:
394
+ ValueError: If template not found
395
+ """
396
+ template = self.templates.get(template_id)
397
+ if not template:
398
+ raise ValueError(f"Unknown template: {template_id}")
399
+
400
+ spec = template.create_spec(customizations)
401
+
402
+ return AgentBlueprint(
403
+ spec=spec,
404
+ generated_from="template",
405
+ template_id=template_id,
406
+ customizations=customizations or {},
407
+ )
408
+
409
+ def generate_agents_for_requirements(
410
+ self,
411
+ requirements: dict[str, Any],
412
+ ) -> list[AgentBlueprint]:
413
+ """Generate appropriate agents based on requirements.
414
+
415
+ This is the core intelligent generation that maps requirements
416
+ (from Socratic questioning) to agent configurations.
417
+
418
+ Args:
419
+ requirements: Requirements gathered from Socratic session
420
+ - quality_focus: list of quality attributes
421
+ - languages: list of programming languages
422
+ - automation_level: advisory/semi_auto/fully_auto
423
+ - domain: domain (e.g., "code_review", "testing")
424
+
425
+ Returns:
426
+ List of AgentBlueprints for a complete team
427
+ """
428
+ agents: list[AgentBlueprint] = []
429
+ quality_focus = requirements.get("quality_focus", [])
430
+ languages = requirements.get("languages", [])
431
+ automation = requirements.get("automation_level", "semi_auto")
432
+
433
+ # Map quality focus to agent templates
434
+ quality_to_templates = {
435
+ "security": ["security_reviewer"],
436
+ "performance": ["performance_analyzer"],
437
+ "maintainability": ["code_quality_reviewer", "documentation_writer"],
438
+ "reliability": ["code_quality_reviewer", "test_generator"],
439
+ "testability": ["test_generator"],
440
+ }
441
+
442
+ # Collect needed templates
443
+ needed_templates: set[str] = set()
444
+ for quality in quality_focus:
445
+ templates = quality_to_templates.get(quality, [])
446
+ needed_templates.update(templates)
447
+
448
+ # Default to basic code review if no specific focus
449
+ if not needed_templates:
450
+ needed_templates.add("code_quality_reviewer")
451
+
452
+ # Add synthesizer for results aggregation
453
+ if len(needed_templates) > 1:
454
+ needed_templates.add("result_synthesizer")
455
+
456
+ # Generate agent for each template
457
+ for template_id in needed_templates:
458
+ customizations = {
459
+ "languages": languages,
460
+ "quality_focus": quality_focus,
461
+ }
462
+
463
+ # Adjust for automation level
464
+ if automation == "fully_auto":
465
+ customizations["instructions"] = [
466
+ "Apply fixes automatically where safe",
467
+ "Minimize human review requirements",
468
+ ]
469
+ elif automation == "advisory":
470
+ customizations["instructions"] = [
471
+ "Provide recommendations only",
472
+ "Do not modify any files",
473
+ ]
474
+
475
+ try:
476
+ agent = self.generate_agent_from_template(template_id, customizations)
477
+ agents.append(agent)
478
+ except ValueError:
479
+ logger.warning(f"Template not found: {template_id}")
480
+
481
+ return agents
482
+
483
+ def generate_workflow(
484
+ self,
485
+ blueprint: WorkflowBlueprint,
486
+ ) -> GeneratedWorkflow:
487
+ """Generate a complete workflow from a blueprint.
488
+
489
+ Args:
490
+ blueprint: The workflow blueprint to generate from
491
+
492
+ Returns:
493
+ GeneratedWorkflow ready for execution
494
+ """
495
+ # Validate blueprint
496
+ is_valid, errors = blueprint.validate()
497
+ if not is_valid:
498
+ raise ValueError(f"Invalid blueprint: {'; '.join(errors)}")
499
+
500
+ # Generate XML agents from blueprints
501
+ xml_agents = []
502
+ for agent_bp in blueprint.agents:
503
+ xml_agent = self._create_xml_agent(agent_bp.spec)
504
+ xml_agents.append(xml_agent)
505
+
506
+ # Build stage configuration
507
+ stages_config = []
508
+ for stage in blueprint.stages:
509
+ stages_config.append(
510
+ {
511
+ "id": stage.id,
512
+ "name": stage.name,
513
+ "agents": stage.agent_ids,
514
+ "parallel": stage.parallel,
515
+ "depends_on": stage.depends_on,
516
+ "timeout": stage.timeout,
517
+ }
518
+ )
519
+
520
+ return GeneratedWorkflow(
521
+ blueprint=blueprint,
522
+ agents=xml_agents,
523
+ stages=stages_config,
524
+ generated_at=datetime.now().isoformat(),
525
+ )
526
+
527
+ def _create_xml_agent(self, spec: AgentSpec) -> XMLAgent:
528
+ """Create an XMLAgent from a spec."""
529
+ from ..workflows.xml_enhanced_crew import XMLAgent
530
+
531
+ return XMLAgent(
532
+ role=spec.name,
533
+ goal=spec.goal,
534
+ backstory=spec.backstory,
535
+ expertise_level="expert" if spec.model_tier != "cheap" else "competent",
536
+ custom_instructions=spec.custom_instructions,
537
+ )
538
+
539
+ def create_workflow_blueprint(
540
+ self,
541
+ name: str,
542
+ description: str,
543
+ agents: list[AgentBlueprint],
544
+ quality_focus: list[str],
545
+ automation_level: str,
546
+ success_criteria: SuccessCriteria | None = None,
547
+ ) -> WorkflowBlueprint:
548
+ """Create a workflow blueprint with automatic staging.
549
+
550
+ Args:
551
+ name: Workflow name
552
+ description: Workflow description
553
+ agents: Agent blueprints to include
554
+ quality_focus: Quality attributes to optimize for
555
+ automation_level: Level of automation
556
+ success_criteria: Optional success criteria
557
+
558
+ Returns:
559
+ Complete WorkflowBlueprint
560
+ """
561
+ # Group agents by role for staging
562
+ analyzers = [
563
+ a
564
+ for a in agents
565
+ if a.spec.role in (AgentRole.ANALYZER, AgentRole.REVIEWER, AgentRole.AUDITOR)
566
+ ]
567
+ generators = [a for a in agents if a.spec.role == AgentRole.GENERATOR]
568
+ reporters = [a for a in agents if a.spec.role == AgentRole.REPORTER]
569
+
570
+ stages = []
571
+
572
+ # Stage 1: Analysis (parallel)
573
+ if analyzers:
574
+ stages.append(
575
+ StageSpec(
576
+ id="analysis",
577
+ name="Analysis",
578
+ description="Analyze code and identify issues",
579
+ agent_ids=[a.spec.id for a in analyzers],
580
+ parallel=True,
581
+ output_aggregation="merge",
582
+ )
583
+ )
584
+
585
+ # Stage 2: Generation (sequential, depends on analysis)
586
+ if generators:
587
+ stages.append(
588
+ StageSpec(
589
+ id="generation",
590
+ name="Generation",
591
+ description="Generate fixes and improvements",
592
+ agent_ids=[a.spec.id for a in generators],
593
+ parallel=False,
594
+ depends_on=["analysis"] if analyzers else [],
595
+ )
596
+ )
597
+
598
+ # Stage 3: Synthesis (always last)
599
+ if reporters:
600
+ depends = []
601
+ if analyzers:
602
+ depends.append("analysis")
603
+ if generators:
604
+ depends.append("generation")
605
+
606
+ stages.append(
607
+ StageSpec(
608
+ id="synthesis",
609
+ name="Synthesis",
610
+ description="Synthesize findings into report",
611
+ agent_ids=[a.spec.id for a in reporters],
612
+ parallel=False,
613
+ depends_on=depends,
614
+ )
615
+ )
616
+
617
+ return WorkflowBlueprint(
618
+ name=name,
619
+ description=description,
620
+ agents=agents,
621
+ stages=stages,
622
+ quality_focus=quality_focus,
623
+ automation_level=automation_level,
624
+ success_criteria=success_criteria,
625
+ generated_at=datetime.now().isoformat(),
626
+ )
627
+
628
+
629
+ @dataclass
630
+ class GeneratedWorkflow:
631
+ """A generated, runnable workflow.
632
+
633
+ Contains all the components needed to execute the workflow.
634
+ """
635
+
636
+ # Source blueprint
637
+ blueprint: WorkflowBlueprint
638
+
639
+ # Generated XMLAgent instances
640
+ agents: list[Any] # XMLAgent
641
+
642
+ # Stage configuration
643
+ stages: list[dict[str, Any]]
644
+
645
+ # Generation timestamp
646
+ generated_at: str = ""
647
+
648
+ # Whether workflow has been validated
649
+ validated: bool = False
650
+
651
+ async def execute(
652
+ self,
653
+ input_data: dict[str, Any],
654
+ progress_callback: Any = None,
655
+ ) -> dict[str, Any]:
656
+ """Execute the workflow.
657
+
658
+ Args:
659
+ input_data: Input data for the workflow
660
+ progress_callback: Optional progress callback
661
+
662
+ Returns:
663
+ Workflow results
664
+ """
665
+ # This is a simplified execution - real implementation would
666
+ # integrate with BaseWorkflow
667
+ results: dict[str, Any] = {
668
+ "stages": {},
669
+ "agents": {},
670
+ "final_output": None,
671
+ "success": False,
672
+ }
673
+
674
+ for stage_config in self.stages:
675
+ stage_id = stage_config["id"]
676
+ agent_ids = stage_config["agents"]
677
+
678
+ stage_results = []
679
+ for agent_id in agent_ids:
680
+ # Find agent
681
+ agent = next(
682
+ (
683
+ a
684
+ for a in self.agents
685
+ if hasattr(a, "role") and self._match_agent(a, agent_id)
686
+ ),
687
+ None,
688
+ )
689
+ if agent:
690
+ # Execute agent (simplified)
691
+ result = {
692
+ "agent_id": agent_id,
693
+ "status": "completed",
694
+ "output": f"Agent {agent_id} completed",
695
+ }
696
+ stage_results.append(result)
697
+
698
+ results["stages"][stage_id] = stage_results
699
+
700
+ results["success"] = True
701
+ results["final_output"] = results["stages"]
702
+
703
+ return results
704
+
705
+ def _match_agent(self, agent: Any, agent_id: str) -> bool:
706
+ """Check if an agent matches an ID."""
707
+ # Match by role name (simplified)
708
+ if hasattr(agent, "role"):
709
+ return agent_id.replace("_", " ").lower() in agent.role.lower()
710
+ return False
711
+
712
+ def describe(self) -> str:
713
+ """Get human-readable description of the workflow."""
714
+ lines = [
715
+ f"Workflow: {self.blueprint.name}",
716
+ f"Description: {self.blueprint.description}",
717
+ "",
718
+ f"Agents ({len(self.agents)}):",
719
+ ]
720
+
721
+ for agent in self.agents:
722
+ if hasattr(agent, "role"):
723
+ lines.append(f" - {agent.role}: {getattr(agent, 'goal', 'N/A')}")
724
+
725
+ lines.append("")
726
+ lines.append(f"Stages ({len(self.stages)}):")
727
+
728
+ for stage in self.stages:
729
+ parallel = "parallel" if stage.get("parallel") else "sequential"
730
+ lines.append(f" - {stage['name']} ({parallel}): {', '.join(stage['agents'])}")
731
+
732
+ return "\n".join(lines)