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.
- attune/__init__.py +358 -0
- attune/adaptive/__init__.py +13 -0
- attune/adaptive/task_complexity.py +127 -0
- attune/agent_monitoring.py +414 -0
- attune/cache/__init__.py +117 -0
- attune/cache/base.py +166 -0
- attune/cache/dependency_manager.py +256 -0
- attune/cache/hash_only.py +251 -0
- attune/cache/hybrid.py +457 -0
- attune/cache/storage.py +285 -0
- attune/cache_monitor.py +356 -0
- attune/cache_stats.py +298 -0
- attune/cli/__init__.py +152 -0
- attune/cli/__main__.py +12 -0
- attune/cli/commands/__init__.py +1 -0
- attune/cli/commands/batch.py +264 -0
- attune/cli/commands/cache.py +248 -0
- attune/cli/commands/help.py +331 -0
- attune/cli/commands/info.py +140 -0
- attune/cli/commands/inspect.py +436 -0
- attune/cli/commands/inspection.py +57 -0
- attune/cli/commands/memory.py +48 -0
- attune/cli/commands/metrics.py +92 -0
- attune/cli/commands/orchestrate.py +184 -0
- attune/cli/commands/patterns.py +207 -0
- attune/cli/commands/profiling.py +202 -0
- attune/cli/commands/provider.py +98 -0
- attune/cli/commands/routing.py +285 -0
- attune/cli/commands/setup.py +96 -0
- attune/cli/commands/status.py +235 -0
- attune/cli/commands/sync.py +166 -0
- attune/cli/commands/tier.py +121 -0
- attune/cli/commands/utilities.py +114 -0
- attune/cli/commands/workflow.py +579 -0
- attune/cli/core.py +32 -0
- attune/cli/parsers/__init__.py +68 -0
- attune/cli/parsers/batch.py +118 -0
- attune/cli/parsers/cache.py +65 -0
- attune/cli/parsers/help.py +41 -0
- attune/cli/parsers/info.py +26 -0
- attune/cli/parsers/inspect.py +66 -0
- attune/cli/parsers/metrics.py +42 -0
- attune/cli/parsers/orchestrate.py +61 -0
- attune/cli/parsers/patterns.py +54 -0
- attune/cli/parsers/provider.py +40 -0
- attune/cli/parsers/routing.py +110 -0
- attune/cli/parsers/setup.py +42 -0
- attune/cli/parsers/status.py +47 -0
- attune/cli/parsers/sync.py +31 -0
- attune/cli/parsers/tier.py +33 -0
- attune/cli/parsers/workflow.py +77 -0
- attune/cli/utils/__init__.py +1 -0
- attune/cli/utils/data.py +242 -0
- attune/cli/utils/helpers.py +68 -0
- attune/cli_legacy.py +3957 -0
- attune/cli_minimal.py +1159 -0
- attune/cli_router.py +437 -0
- attune/cli_unified.py +814 -0
- attune/config/__init__.py +66 -0
- attune/config/xml_config.py +286 -0
- attune/config.py +545 -0
- attune/coordination.py +870 -0
- attune/core.py +1511 -0
- attune/core_modules/__init__.py +15 -0
- attune/cost_tracker.py +626 -0
- attune/dashboard/__init__.py +41 -0
- attune/dashboard/app.py +512 -0
- attune/dashboard/simple_server.py +435 -0
- attune/dashboard/standalone_server.py +547 -0
- attune/discovery.py +306 -0
- attune/emergence.py +306 -0
- attune/exceptions.py +123 -0
- attune/feedback_loops.py +373 -0
- attune/hot_reload/README.md +473 -0
- attune/hot_reload/__init__.py +62 -0
- attune/hot_reload/config.py +83 -0
- attune/hot_reload/integration.py +229 -0
- attune/hot_reload/reloader.py +298 -0
- attune/hot_reload/watcher.py +183 -0
- attune/hot_reload/websocket.py +177 -0
- attune/levels.py +577 -0
- attune/leverage_points.py +441 -0
- attune/logging_config.py +261 -0
- attune/mcp/__init__.py +10 -0
- attune/mcp/server.py +506 -0
- attune/memory/__init__.py +237 -0
- attune/memory/claude_memory.py +469 -0
- attune/memory/config.py +224 -0
- attune/memory/control_panel.py +1290 -0
- attune/memory/control_panel_support.py +145 -0
- attune/memory/cross_session.py +845 -0
- attune/memory/edges.py +179 -0
- attune/memory/encryption.py +159 -0
- attune/memory/file_session.py +770 -0
- attune/memory/graph.py +570 -0
- attune/memory/long_term.py +913 -0
- attune/memory/long_term_types.py +99 -0
- attune/memory/mixins/__init__.py +25 -0
- attune/memory/mixins/backend_init_mixin.py +249 -0
- attune/memory/mixins/capabilities_mixin.py +208 -0
- attune/memory/mixins/handoff_mixin.py +208 -0
- attune/memory/mixins/lifecycle_mixin.py +49 -0
- attune/memory/mixins/long_term_mixin.py +352 -0
- attune/memory/mixins/promotion_mixin.py +109 -0
- attune/memory/mixins/short_term_mixin.py +182 -0
- attune/memory/nodes.py +179 -0
- attune/memory/redis_bootstrap.py +540 -0
- attune/memory/security/__init__.py +31 -0
- attune/memory/security/audit_logger.py +932 -0
- attune/memory/security/pii_scrubber.py +640 -0
- attune/memory/security/secrets_detector.py +678 -0
- attune/memory/short_term.py +2192 -0
- attune/memory/simple_storage.py +302 -0
- attune/memory/storage/__init__.py +15 -0
- attune/memory/storage_backend.py +167 -0
- attune/memory/summary_index.py +583 -0
- attune/memory/types.py +446 -0
- attune/memory/unified.py +182 -0
- attune/meta_workflows/__init__.py +74 -0
- attune/meta_workflows/agent_creator.py +248 -0
- attune/meta_workflows/builtin_templates.py +567 -0
- attune/meta_workflows/cli_commands/__init__.py +56 -0
- attune/meta_workflows/cli_commands/agent_commands.py +321 -0
- attune/meta_workflows/cli_commands/analytics_commands.py +442 -0
- attune/meta_workflows/cli_commands/config_commands.py +232 -0
- attune/meta_workflows/cli_commands/memory_commands.py +182 -0
- attune/meta_workflows/cli_commands/template_commands.py +354 -0
- attune/meta_workflows/cli_commands/workflow_commands.py +382 -0
- attune/meta_workflows/cli_meta_workflows.py +59 -0
- attune/meta_workflows/form_engine.py +292 -0
- attune/meta_workflows/intent_detector.py +409 -0
- attune/meta_workflows/models.py +569 -0
- attune/meta_workflows/pattern_learner.py +738 -0
- attune/meta_workflows/plan_generator.py +384 -0
- attune/meta_workflows/session_context.py +397 -0
- attune/meta_workflows/template_registry.py +229 -0
- attune/meta_workflows/workflow.py +984 -0
- attune/metrics/__init__.py +12 -0
- attune/metrics/collector.py +31 -0
- attune/metrics/prompt_metrics.py +194 -0
- attune/models/__init__.py +172 -0
- attune/models/__main__.py +13 -0
- attune/models/adaptive_routing.py +437 -0
- attune/models/auth_cli.py +444 -0
- attune/models/auth_strategy.py +450 -0
- attune/models/cli.py +655 -0
- attune/models/empathy_executor.py +354 -0
- attune/models/executor.py +257 -0
- attune/models/fallback.py +762 -0
- attune/models/provider_config.py +282 -0
- attune/models/registry.py +472 -0
- attune/models/tasks.py +359 -0
- attune/models/telemetry/__init__.py +71 -0
- attune/models/telemetry/analytics.py +594 -0
- attune/models/telemetry/backend.py +196 -0
- attune/models/telemetry/data_models.py +431 -0
- attune/models/telemetry/storage.py +489 -0
- attune/models/token_estimator.py +420 -0
- attune/models/validation.py +280 -0
- attune/monitoring/__init__.py +52 -0
- attune/monitoring/alerts.py +946 -0
- attune/monitoring/alerts_cli.py +448 -0
- attune/monitoring/multi_backend.py +271 -0
- attune/monitoring/otel_backend.py +362 -0
- attune/optimization/__init__.py +19 -0
- attune/optimization/context_optimizer.py +272 -0
- attune/orchestration/__init__.py +67 -0
- attune/orchestration/agent_templates.py +707 -0
- attune/orchestration/config_store.py +499 -0
- attune/orchestration/execution_strategies.py +2111 -0
- attune/orchestration/meta_orchestrator.py +1168 -0
- attune/orchestration/pattern_learner.py +696 -0
- attune/orchestration/real_tools.py +931 -0
- attune/pattern_cache.py +187 -0
- attune/pattern_library.py +542 -0
- attune/patterns/debugging/all_patterns.json +81 -0
- attune/patterns/debugging/workflow_20260107_1770825e.json +77 -0
- attune/patterns/refactoring_memory.json +89 -0
- attune/persistence.py +564 -0
- attune/platform_utils.py +265 -0
- attune/plugins/__init__.py +28 -0
- attune/plugins/base.py +361 -0
- attune/plugins/registry.py +268 -0
- attune/project_index/__init__.py +32 -0
- attune/project_index/cli.py +335 -0
- attune/project_index/index.py +667 -0
- attune/project_index/models.py +504 -0
- attune/project_index/reports.py +474 -0
- attune/project_index/scanner.py +777 -0
- attune/project_index/scanner_parallel.py +291 -0
- attune/prompts/__init__.py +61 -0
- attune/prompts/config.py +77 -0
- attune/prompts/context.py +177 -0
- attune/prompts/parser.py +285 -0
- attune/prompts/registry.py +313 -0
- attune/prompts/templates.py +208 -0
- attune/redis_config.py +302 -0
- attune/redis_memory.py +799 -0
- attune/resilience/__init__.py +56 -0
- attune/resilience/circuit_breaker.py +256 -0
- attune/resilience/fallback.py +179 -0
- attune/resilience/health.py +300 -0
- attune/resilience/retry.py +209 -0
- attune/resilience/timeout.py +135 -0
- attune/routing/__init__.py +43 -0
- attune/routing/chain_executor.py +433 -0
- attune/routing/classifier.py +217 -0
- attune/routing/smart_router.py +234 -0
- attune/routing/workflow_registry.py +343 -0
- attune/scaffolding/README.md +589 -0
- attune/scaffolding/__init__.py +35 -0
- attune/scaffolding/__main__.py +14 -0
- attune/scaffolding/cli.py +240 -0
- attune/scaffolding/templates/base_wizard.py.jinja2 +121 -0
- attune/scaffolding/templates/coach_wizard.py.jinja2 +321 -0
- attune/scaffolding/templates/domain_wizard.py.jinja2 +408 -0
- attune/scaffolding/templates/linear_flow_wizard.py.jinja2 +203 -0
- attune/socratic/__init__.py +256 -0
- attune/socratic/ab_testing.py +958 -0
- attune/socratic/blueprint.py +533 -0
- attune/socratic/cli.py +703 -0
- attune/socratic/collaboration.py +1114 -0
- attune/socratic/domain_templates.py +924 -0
- attune/socratic/embeddings.py +738 -0
- attune/socratic/engine.py +794 -0
- attune/socratic/explainer.py +682 -0
- attune/socratic/feedback.py +772 -0
- attune/socratic/forms.py +629 -0
- attune/socratic/generator.py +732 -0
- attune/socratic/llm_analyzer.py +637 -0
- attune/socratic/mcp_server.py +702 -0
- attune/socratic/session.py +312 -0
- attune/socratic/storage.py +667 -0
- attune/socratic/success.py +730 -0
- attune/socratic/visual_editor.py +860 -0
- attune/socratic/web_ui.py +958 -0
- attune/telemetry/__init__.py +39 -0
- attune/telemetry/agent_coordination.py +475 -0
- attune/telemetry/agent_tracking.py +367 -0
- attune/telemetry/approval_gates.py +545 -0
- attune/telemetry/cli.py +1231 -0
- attune/telemetry/commands/__init__.py +14 -0
- attune/telemetry/commands/dashboard_commands.py +696 -0
- attune/telemetry/event_streaming.py +409 -0
- attune/telemetry/feedback_loop.py +567 -0
- attune/telemetry/usage_tracker.py +591 -0
- attune/templates.py +754 -0
- attune/test_generator/__init__.py +38 -0
- attune/test_generator/__main__.py +14 -0
- attune/test_generator/cli.py +234 -0
- attune/test_generator/generator.py +355 -0
- attune/test_generator/risk_analyzer.py +216 -0
- attune/test_generator/templates/unit_test.py.jinja2 +272 -0
- attune/tier_recommender.py +384 -0
- attune/tools.py +183 -0
- attune/trust/__init__.py +28 -0
- attune/trust/circuit_breaker.py +579 -0
- attune/trust_building.py +527 -0
- attune/validation/__init__.py +19 -0
- attune/validation/xml_validator.py +281 -0
- attune/vscode_bridge.py +173 -0
- attune/workflow_commands.py +780 -0
- attune/workflow_patterns/__init__.py +33 -0
- attune/workflow_patterns/behavior.py +249 -0
- attune/workflow_patterns/core.py +76 -0
- attune/workflow_patterns/output.py +99 -0
- attune/workflow_patterns/registry.py +255 -0
- attune/workflow_patterns/structural.py +288 -0
- attune/workflows/__init__.py +539 -0
- attune/workflows/autonomous_test_gen.py +1268 -0
- attune/workflows/base.py +2667 -0
- attune/workflows/batch_processing.py +342 -0
- attune/workflows/bug_predict.py +1084 -0
- attune/workflows/builder.py +273 -0
- attune/workflows/caching.py +253 -0
- attune/workflows/code_review.py +1048 -0
- attune/workflows/code_review_adapters.py +312 -0
- attune/workflows/code_review_pipeline.py +722 -0
- attune/workflows/config.py +645 -0
- attune/workflows/dependency_check.py +644 -0
- attune/workflows/document_gen/__init__.py +25 -0
- attune/workflows/document_gen/config.py +30 -0
- attune/workflows/document_gen/report_formatter.py +162 -0
- attune/workflows/document_gen/workflow.py +1426 -0
- attune/workflows/document_manager.py +216 -0
- attune/workflows/document_manager_README.md +134 -0
- attune/workflows/documentation_orchestrator.py +1205 -0
- attune/workflows/history.py +510 -0
- attune/workflows/keyboard_shortcuts/__init__.py +39 -0
- attune/workflows/keyboard_shortcuts/generators.py +391 -0
- attune/workflows/keyboard_shortcuts/parsers.py +416 -0
- attune/workflows/keyboard_shortcuts/prompts.py +295 -0
- attune/workflows/keyboard_shortcuts/schema.py +193 -0
- attune/workflows/keyboard_shortcuts/workflow.py +509 -0
- attune/workflows/llm_base.py +363 -0
- attune/workflows/manage_docs.py +87 -0
- attune/workflows/manage_docs_README.md +134 -0
- attune/workflows/manage_documentation.py +821 -0
- attune/workflows/new_sample_workflow1.py +149 -0
- attune/workflows/new_sample_workflow1_README.md +150 -0
- attune/workflows/orchestrated_health_check.py +849 -0
- attune/workflows/orchestrated_release_prep.py +600 -0
- attune/workflows/output.py +413 -0
- attune/workflows/perf_audit.py +863 -0
- attune/workflows/pr_review.py +762 -0
- attune/workflows/progress.py +785 -0
- attune/workflows/progress_server.py +322 -0
- attune/workflows/progressive/README 2.md +454 -0
- attune/workflows/progressive/README.md +454 -0
- attune/workflows/progressive/__init__.py +82 -0
- attune/workflows/progressive/cli.py +219 -0
- attune/workflows/progressive/core.py +488 -0
- attune/workflows/progressive/orchestrator.py +723 -0
- attune/workflows/progressive/reports.py +520 -0
- attune/workflows/progressive/telemetry.py +274 -0
- attune/workflows/progressive/test_gen.py +495 -0
- attune/workflows/progressive/workflow.py +589 -0
- attune/workflows/refactor_plan.py +694 -0
- attune/workflows/release_prep.py +895 -0
- attune/workflows/release_prep_crew.py +969 -0
- attune/workflows/research_synthesis.py +404 -0
- attune/workflows/routing.py +168 -0
- attune/workflows/secure_release.py +593 -0
- attune/workflows/security_adapters.py +297 -0
- attune/workflows/security_audit.py +1329 -0
- attune/workflows/security_audit_phase3.py +355 -0
- attune/workflows/seo_optimization.py +633 -0
- attune/workflows/step_config.py +234 -0
- attune/workflows/telemetry_mixin.py +269 -0
- attune/workflows/test5.py +125 -0
- attune/workflows/test5_README.md +158 -0
- attune/workflows/test_coverage_boost_crew.py +849 -0
- attune/workflows/test_gen/__init__.py +52 -0
- attune/workflows/test_gen/ast_analyzer.py +249 -0
- attune/workflows/test_gen/config.py +88 -0
- attune/workflows/test_gen/data_models.py +38 -0
- attune/workflows/test_gen/report_formatter.py +289 -0
- attune/workflows/test_gen/test_templates.py +381 -0
- attune/workflows/test_gen/workflow.py +655 -0
- attune/workflows/test_gen.py +54 -0
- attune/workflows/test_gen_behavioral.py +477 -0
- attune/workflows/test_gen_parallel.py +341 -0
- attune/workflows/test_lifecycle.py +526 -0
- attune/workflows/test_maintenance.py +627 -0
- attune/workflows/test_maintenance_cli.py +590 -0
- attune/workflows/test_maintenance_crew.py +840 -0
- attune/workflows/test_runner.py +622 -0
- attune/workflows/tier_tracking.py +531 -0
- attune/workflows/xml_enhanced_crew.py +285 -0
- attune_ai-2.0.0.dist-info/METADATA +1026 -0
- attune_ai-2.0.0.dist-info/RECORD +457 -0
- attune_ai-2.0.0.dist-info/WHEEL +5 -0
- attune_ai-2.0.0.dist-info/entry_points.txt +26 -0
- attune_ai-2.0.0.dist-info/licenses/LICENSE +201 -0
- attune_ai-2.0.0.dist-info/licenses/LICENSE_CHANGE_ANNOUNCEMENT.md +101 -0
- attune_ai-2.0.0.dist-info/top_level.txt +5 -0
- attune_healthcare/__init__.py +13 -0
- attune_healthcare/monitors/__init__.py +9 -0
- attune_healthcare/monitors/clinical_protocol_monitor.py +315 -0
- attune_healthcare/monitors/monitoring/__init__.py +44 -0
- attune_healthcare/monitors/monitoring/protocol_checker.py +300 -0
- attune_healthcare/monitors/monitoring/protocol_loader.py +214 -0
- attune_healthcare/monitors/monitoring/sensor_parsers.py +306 -0
- attune_healthcare/monitors/monitoring/trajectory_analyzer.py +389 -0
- attune_llm/README.md +553 -0
- attune_llm/__init__.py +28 -0
- attune_llm/agent_factory/__init__.py +53 -0
- attune_llm/agent_factory/adapters/__init__.py +85 -0
- attune_llm/agent_factory/adapters/autogen_adapter.py +312 -0
- attune_llm/agent_factory/adapters/crewai_adapter.py +483 -0
- attune_llm/agent_factory/adapters/haystack_adapter.py +298 -0
- attune_llm/agent_factory/adapters/langchain_adapter.py +362 -0
- attune_llm/agent_factory/adapters/langgraph_adapter.py +333 -0
- attune_llm/agent_factory/adapters/native.py +228 -0
- attune_llm/agent_factory/adapters/wizard_adapter.py +423 -0
- attune_llm/agent_factory/base.py +305 -0
- attune_llm/agent_factory/crews/__init__.py +67 -0
- attune_llm/agent_factory/crews/code_review.py +1113 -0
- attune_llm/agent_factory/crews/health_check.py +1262 -0
- attune_llm/agent_factory/crews/refactoring.py +1128 -0
- attune_llm/agent_factory/crews/security_audit.py +1018 -0
- attune_llm/agent_factory/decorators.py +287 -0
- attune_llm/agent_factory/factory.py +558 -0
- attune_llm/agent_factory/framework.py +193 -0
- attune_llm/agent_factory/memory_integration.py +328 -0
- attune_llm/agent_factory/resilient.py +320 -0
- attune_llm/agents_md/__init__.py +22 -0
- attune_llm/agents_md/loader.py +218 -0
- attune_llm/agents_md/parser.py +271 -0
- attune_llm/agents_md/registry.py +307 -0
- attune_llm/claude_memory.py +466 -0
- attune_llm/cli/__init__.py +8 -0
- attune_llm/cli/sync_claude.py +487 -0
- attune_llm/code_health.py +1313 -0
- attune_llm/commands/__init__.py +51 -0
- attune_llm/commands/context.py +375 -0
- attune_llm/commands/loader.py +301 -0
- attune_llm/commands/models.py +231 -0
- attune_llm/commands/parser.py +371 -0
- attune_llm/commands/registry.py +429 -0
- attune_llm/config/__init__.py +29 -0
- attune_llm/config/unified.py +291 -0
- attune_llm/context/__init__.py +22 -0
- attune_llm/context/compaction.py +455 -0
- attune_llm/context/manager.py +434 -0
- attune_llm/contextual_patterns.py +361 -0
- attune_llm/core.py +907 -0
- attune_llm/git_pattern_extractor.py +435 -0
- attune_llm/hooks/__init__.py +24 -0
- attune_llm/hooks/config.py +306 -0
- attune_llm/hooks/executor.py +289 -0
- attune_llm/hooks/registry.py +302 -0
- attune_llm/hooks/scripts/__init__.py +39 -0
- attune_llm/hooks/scripts/evaluate_session.py +201 -0
- attune_llm/hooks/scripts/first_time_init.py +285 -0
- attune_llm/hooks/scripts/pre_compact.py +207 -0
- attune_llm/hooks/scripts/session_end.py +183 -0
- attune_llm/hooks/scripts/session_start.py +163 -0
- attune_llm/hooks/scripts/suggest_compact.py +225 -0
- attune_llm/learning/__init__.py +30 -0
- attune_llm/learning/evaluator.py +438 -0
- attune_llm/learning/extractor.py +514 -0
- attune_llm/learning/storage.py +560 -0
- attune_llm/levels.py +227 -0
- attune_llm/pattern_confidence.py +414 -0
- attune_llm/pattern_resolver.py +272 -0
- attune_llm/pattern_summary.py +350 -0
- attune_llm/providers.py +967 -0
- attune_llm/routing/__init__.py +32 -0
- attune_llm/routing/model_router.py +362 -0
- attune_llm/security/IMPLEMENTATION_SUMMARY.md +413 -0
- attune_llm/security/PHASE2_COMPLETE.md +384 -0
- attune_llm/security/PHASE2_SECRETS_DETECTOR_COMPLETE.md +271 -0
- attune_llm/security/QUICK_REFERENCE.md +316 -0
- attune_llm/security/README.md +262 -0
- attune_llm/security/__init__.py +62 -0
- attune_llm/security/audit_logger.py +929 -0
- attune_llm/security/audit_logger_example.py +152 -0
- attune_llm/security/pii_scrubber.py +640 -0
- attune_llm/security/secrets_detector.py +678 -0
- attune_llm/security/secrets_detector_example.py +304 -0
- attune_llm/security/secure_memdocs.py +1192 -0
- attune_llm/security/secure_memdocs_example.py +278 -0
- attune_llm/session_status.py +745 -0
- attune_llm/state.py +246 -0
- attune_llm/utils/__init__.py +5 -0
- attune_llm/utils/tokens.py +349 -0
- attune_software/SOFTWARE_PLUGIN_README.md +57 -0
- attune_software/__init__.py +13 -0
- attune_software/cli/__init__.py +120 -0
- attune_software/cli/inspect.py +362 -0
- attune_software/cli.py +574 -0
- attune_software/plugin.py +188 -0
- workflow_scaffolding/__init__.py +11 -0
- workflow_scaffolding/__main__.py +12 -0
- workflow_scaffolding/cli.py +206 -0
- workflow_scaffolding/generator.py +265 -0
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
"""Plan Generator for Meta-Workflows.
|
|
2
|
+
|
|
3
|
+
Generates execution plans from meta-workflow templates that can be executed
|
|
4
|
+
by Claude Code instead of making direct API calls.
|
|
5
|
+
|
|
6
|
+
This enables users to leverage their Claude Max subscription instead of
|
|
7
|
+
paying per-API-call costs.
|
|
8
|
+
|
|
9
|
+
Output formats:
|
|
10
|
+
- Markdown: Human-readable plan for interactive use
|
|
11
|
+
- Claude Code Skill: .claude/commands/ compatible format
|
|
12
|
+
- JSON: Programmatic consumption
|
|
13
|
+
|
|
14
|
+
Created: 2026-01-20
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from dataclasses import dataclass
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from typing import Literal
|
|
20
|
+
|
|
21
|
+
from attune.meta_workflows.models import (
|
|
22
|
+
AgentCompositionRule,
|
|
23
|
+
MetaWorkflowTemplate,
|
|
24
|
+
TierStrategy,
|
|
25
|
+
)
|
|
26
|
+
from attune.orchestration.agent_templates import get_template
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class AgentStep:
|
|
31
|
+
"""A single step in the execution plan."""
|
|
32
|
+
|
|
33
|
+
order: int
|
|
34
|
+
role: str
|
|
35
|
+
tier_recommendation: str
|
|
36
|
+
tools: list[str]
|
|
37
|
+
prompt: str
|
|
38
|
+
success_criteria: list[str]
|
|
39
|
+
config: dict
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass
|
|
43
|
+
class ExecutionPlan:
|
|
44
|
+
"""Complete execution plan for a meta-workflow."""
|
|
45
|
+
|
|
46
|
+
template_id: str
|
|
47
|
+
template_name: str
|
|
48
|
+
generated_at: str
|
|
49
|
+
form_responses: dict
|
|
50
|
+
steps: list[AgentStep]
|
|
51
|
+
synthesis_prompt: str
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class PlanGenerator:
|
|
55
|
+
"""Generates execution plans from meta-workflow templates."""
|
|
56
|
+
|
|
57
|
+
# Map tier strategies to Claude Code model recommendations
|
|
58
|
+
TIER_TO_MODEL = {
|
|
59
|
+
TierStrategy.CHEAP_ONLY: "haiku",
|
|
60
|
+
TierStrategy.PROGRESSIVE: "sonnet (escalate to opus if needed)",
|
|
61
|
+
TierStrategy.CAPABLE_FIRST: "sonnet",
|
|
62
|
+
TierStrategy.PREMIUM_ONLY: "opus",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
def __init__(self, template: MetaWorkflowTemplate):
|
|
66
|
+
"""Initialize with a template.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
template: The meta-workflow template to generate a plan from
|
|
70
|
+
"""
|
|
71
|
+
self.template = template
|
|
72
|
+
|
|
73
|
+
def generate(
|
|
74
|
+
self,
|
|
75
|
+
form_responses: dict | None = None,
|
|
76
|
+
use_defaults: bool = True,
|
|
77
|
+
) -> ExecutionPlan:
|
|
78
|
+
"""Generate an execution plan.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
form_responses: User responses to form questions
|
|
82
|
+
use_defaults: Whether to use default values for missing responses
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
ExecutionPlan ready for execution
|
|
86
|
+
"""
|
|
87
|
+
# Collect form responses
|
|
88
|
+
responses = self._collect_responses(form_responses, use_defaults)
|
|
89
|
+
|
|
90
|
+
# Build steps from composition rules
|
|
91
|
+
steps = self._build_steps(responses)
|
|
92
|
+
|
|
93
|
+
# Generate synthesis prompt
|
|
94
|
+
synthesis = self._build_synthesis_prompt(steps)
|
|
95
|
+
|
|
96
|
+
return ExecutionPlan(
|
|
97
|
+
template_id=self.template.template_id,
|
|
98
|
+
template_name=self.template.name,
|
|
99
|
+
generated_at=datetime.now().isoformat(),
|
|
100
|
+
form_responses=responses,
|
|
101
|
+
steps=steps,
|
|
102
|
+
synthesis_prompt=synthesis,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def _collect_responses(
|
|
106
|
+
self,
|
|
107
|
+
provided: dict | None,
|
|
108
|
+
use_defaults: bool,
|
|
109
|
+
) -> dict:
|
|
110
|
+
"""Collect form responses with defaults."""
|
|
111
|
+
responses = {}
|
|
112
|
+
provided = provided or {}
|
|
113
|
+
|
|
114
|
+
for question in self.template.form_schema.questions:
|
|
115
|
+
if question.id in provided:
|
|
116
|
+
responses[question.id] = provided[question.id]
|
|
117
|
+
elif use_defaults and question.default:
|
|
118
|
+
responses[question.id] = question.default
|
|
119
|
+
elif question.required:
|
|
120
|
+
raise ValueError(f"Missing required response: {question.id}")
|
|
121
|
+
|
|
122
|
+
return responses
|
|
123
|
+
|
|
124
|
+
def _build_steps(self, responses: dict) -> list[AgentStep]:
|
|
125
|
+
"""Build execution steps from composition rules."""
|
|
126
|
+
steps = []
|
|
127
|
+
order = 1
|
|
128
|
+
|
|
129
|
+
for rule in self.template.agent_composition_rules:
|
|
130
|
+
# Check if this agent should be included based on responses
|
|
131
|
+
if not self._should_include_agent(rule, responses):
|
|
132
|
+
continue
|
|
133
|
+
|
|
134
|
+
# Get base template for additional context
|
|
135
|
+
base_template = get_template(rule.base_template)
|
|
136
|
+
|
|
137
|
+
# Build the prompt
|
|
138
|
+
prompt = self._build_agent_prompt(rule, base_template, responses)
|
|
139
|
+
|
|
140
|
+
# Map config from responses
|
|
141
|
+
config = {}
|
|
142
|
+
for response_key, config_key in rule.config_mapping.items():
|
|
143
|
+
if response_key in responses:
|
|
144
|
+
config[config_key] = responses[response_key]
|
|
145
|
+
|
|
146
|
+
steps.append(
|
|
147
|
+
AgentStep(
|
|
148
|
+
order=order,
|
|
149
|
+
role=rule.role,
|
|
150
|
+
tier_recommendation=self.TIER_TO_MODEL.get(rule.tier_strategy, "sonnet"),
|
|
151
|
+
tools=rule.tools,
|
|
152
|
+
prompt=prompt,
|
|
153
|
+
success_criteria=rule.success_criteria,
|
|
154
|
+
config=config,
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
order += 1
|
|
158
|
+
|
|
159
|
+
return steps
|
|
160
|
+
|
|
161
|
+
def _should_include_agent(
|
|
162
|
+
self,
|
|
163
|
+
rule: AgentCompositionRule,
|
|
164
|
+
responses: dict,
|
|
165
|
+
) -> bool:
|
|
166
|
+
"""Check if agent should be included based on required responses."""
|
|
167
|
+
for key, required_value in rule.required_responses.items():
|
|
168
|
+
if responses.get(key) != required_value:
|
|
169
|
+
return False
|
|
170
|
+
return True
|
|
171
|
+
|
|
172
|
+
def _build_agent_prompt(
|
|
173
|
+
self,
|
|
174
|
+
rule: AgentCompositionRule,
|
|
175
|
+
base_template,
|
|
176
|
+
responses: dict,
|
|
177
|
+
) -> str:
|
|
178
|
+
"""Build the prompt for an agent."""
|
|
179
|
+
# Start with base template instructions
|
|
180
|
+
base_instructions = ""
|
|
181
|
+
if base_template:
|
|
182
|
+
base_instructions = base_template.default_instructions
|
|
183
|
+
|
|
184
|
+
# Build context from responses
|
|
185
|
+
context_lines = []
|
|
186
|
+
for key, value in rule.config_mapping.items():
|
|
187
|
+
if key in responses:
|
|
188
|
+
context_lines.append(f"- {value}: {responses[key]}")
|
|
189
|
+
|
|
190
|
+
context = "\n".join(context_lines) if context_lines else "Using default configuration."
|
|
191
|
+
|
|
192
|
+
# Build success criteria checklist
|
|
193
|
+
criteria = "\n".join(f"- [ ] {c}" for c in rule.success_criteria)
|
|
194
|
+
|
|
195
|
+
return f"""You are a {rule.role} analyzing this codebase.
|
|
196
|
+
|
|
197
|
+
{base_instructions}
|
|
198
|
+
|
|
199
|
+
Configuration:
|
|
200
|
+
{context}
|
|
201
|
+
|
|
202
|
+
Success Criteria:
|
|
203
|
+
{criteria}
|
|
204
|
+
|
|
205
|
+
Tools available: {", ".join(rule.tools)}
|
|
206
|
+
|
|
207
|
+
Provide a structured report with findings, issues by severity, and recommendations.
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
def _build_synthesis_prompt(self, steps: list[AgentStep]) -> str:
|
|
211
|
+
"""Build the synthesis prompt that combines all agent outputs."""
|
|
212
|
+
roles = [f"- {step.role}" for step in steps]
|
|
213
|
+
roles_list = "\n".join(roles)
|
|
214
|
+
|
|
215
|
+
return f"""You are synthesizing the results from multiple agents.
|
|
216
|
+
|
|
217
|
+
Combine the outputs from:
|
|
218
|
+
{roles_list}
|
|
219
|
+
|
|
220
|
+
Create a comprehensive report:
|
|
221
|
+
|
|
222
|
+
## Summary
|
|
223
|
+
Overall assessment of the analysis.
|
|
224
|
+
|
|
225
|
+
## Critical Issues (must address)
|
|
226
|
+
List any blockers or critical problems.
|
|
227
|
+
|
|
228
|
+
## Recommendations (should address)
|
|
229
|
+
List improvements and fixes.
|
|
230
|
+
|
|
231
|
+
## Action Items
|
|
232
|
+
Prioritized list of next steps.
|
|
233
|
+
|
|
234
|
+
## Risk Assessment
|
|
235
|
+
What risks exist? What's the recommended path forward?
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
def to_markdown(self, plan: ExecutionPlan) -> str:
|
|
239
|
+
"""Convert plan to markdown format."""
|
|
240
|
+
lines = [
|
|
241
|
+
f"# Execution Plan: {plan.template_name}",
|
|
242
|
+
"",
|
|
243
|
+
"> Generated by Empathy Framework",
|
|
244
|
+
f"> Template: {plan.template_id}",
|
|
245
|
+
f"> Generated: {plan.generated_at}",
|
|
246
|
+
"",
|
|
247
|
+
"## Configuration",
|
|
248
|
+
"",
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
for key, value in plan.form_responses.items():
|
|
252
|
+
lines.append(f"- **{key}**: {value}")
|
|
253
|
+
|
|
254
|
+
lines.extend(["", "---", "", "## Execution Steps", ""])
|
|
255
|
+
|
|
256
|
+
for step in plan.steps:
|
|
257
|
+
lines.extend(
|
|
258
|
+
[
|
|
259
|
+
f"### Step {step.order}: {step.role}",
|
|
260
|
+
"",
|
|
261
|
+
f"**Tier Recommendation**: {step.tier_recommendation}",
|
|
262
|
+
f"**Tools**: {', '.join(step.tools)}",
|
|
263
|
+
"",
|
|
264
|
+
"**Prompt:**",
|
|
265
|
+
"```",
|
|
266
|
+
step.prompt,
|
|
267
|
+
"```",
|
|
268
|
+
"",
|
|
269
|
+
"**Success Criteria:**",
|
|
270
|
+
]
|
|
271
|
+
)
|
|
272
|
+
for criterion in step.success_criteria:
|
|
273
|
+
lines.append(f"- [ ] {criterion}")
|
|
274
|
+
lines.extend(["", "---", ""])
|
|
275
|
+
|
|
276
|
+
lines.extend(
|
|
277
|
+
[
|
|
278
|
+
"## Synthesis",
|
|
279
|
+
"",
|
|
280
|
+
"After all steps complete, run this synthesis:",
|
|
281
|
+
"",
|
|
282
|
+
"```",
|
|
283
|
+
plan.synthesis_prompt,
|
|
284
|
+
"```",
|
|
285
|
+
]
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
return "\n".join(lines)
|
|
289
|
+
|
|
290
|
+
def to_claude_code_skill(self, plan: ExecutionPlan) -> str:
|
|
291
|
+
"""Convert plan to Claude Code skill format.
|
|
292
|
+
|
|
293
|
+
This generates content for .claude/commands/<template-id>.md
|
|
294
|
+
"""
|
|
295
|
+
steps_text = []
|
|
296
|
+
for step in plan.steps:
|
|
297
|
+
steps_text.append(
|
|
298
|
+
f"""
|
|
299
|
+
### {step.role}
|
|
300
|
+
Use the Task tool with subagent_type="Explore" to:
|
|
301
|
+
{step.prompt}
|
|
302
|
+
"""
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
return f"""# {plan.template_name}
|
|
306
|
+
|
|
307
|
+
Execute the {plan.template_name} workflow for this codebase.
|
|
308
|
+
|
|
309
|
+
## Steps
|
|
310
|
+
|
|
311
|
+
{"".join(steps_text)}
|
|
312
|
+
|
|
313
|
+
## Synthesis
|
|
314
|
+
|
|
315
|
+
After completing all steps, synthesize the findings:
|
|
316
|
+
{plan.synthesis_prompt}
|
|
317
|
+
|
|
318
|
+
## Output
|
|
319
|
+
|
|
320
|
+
Provide a final report with:
|
|
321
|
+
1. Overall status (READY / NEEDS WORK / BLOCKED)
|
|
322
|
+
2. Critical issues found
|
|
323
|
+
3. Recommendations
|
|
324
|
+
4. Next steps
|
|
325
|
+
"""
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
def generate_plan(
|
|
329
|
+
template_id: str,
|
|
330
|
+
form_responses: dict | None = None,
|
|
331
|
+
use_defaults: bool = True,
|
|
332
|
+
output_format: Literal["markdown", "skill", "json"] = "markdown",
|
|
333
|
+
) -> str:
|
|
334
|
+
"""Generate an execution plan for a meta-workflow.
|
|
335
|
+
|
|
336
|
+
Args:
|
|
337
|
+
template_id: ID of the template to use
|
|
338
|
+
form_responses: Optional form responses
|
|
339
|
+
use_defaults: Whether to use default values
|
|
340
|
+
output_format: Output format (markdown, skill, or json)
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
Plan in the requested format
|
|
344
|
+
"""
|
|
345
|
+
from attune.meta_workflows.registry import get_template as get_workflow_template
|
|
346
|
+
|
|
347
|
+
template = get_workflow_template(template_id)
|
|
348
|
+
if not template:
|
|
349
|
+
raise ValueError(f"Template not found: {template_id}")
|
|
350
|
+
|
|
351
|
+
generator = PlanGenerator(template)
|
|
352
|
+
plan = generator.generate(form_responses, use_defaults)
|
|
353
|
+
|
|
354
|
+
if output_format == "markdown":
|
|
355
|
+
return generator.to_markdown(plan)
|
|
356
|
+
elif output_format == "skill":
|
|
357
|
+
return generator.to_claude_code_skill(plan)
|
|
358
|
+
elif output_format == "json":
|
|
359
|
+
import json
|
|
360
|
+
|
|
361
|
+
return json.dumps(
|
|
362
|
+
{
|
|
363
|
+
"template_id": plan.template_id,
|
|
364
|
+
"template_name": plan.template_name,
|
|
365
|
+
"generated_at": plan.generated_at,
|
|
366
|
+
"form_responses": plan.form_responses,
|
|
367
|
+
"steps": [
|
|
368
|
+
{
|
|
369
|
+
"order": s.order,
|
|
370
|
+
"role": s.role,
|
|
371
|
+
"tier_recommendation": s.tier_recommendation,
|
|
372
|
+
"tools": s.tools,
|
|
373
|
+
"prompt": s.prompt,
|
|
374
|
+
"success_criteria": s.success_criteria,
|
|
375
|
+
"config": s.config,
|
|
376
|
+
}
|
|
377
|
+
for s in plan.steps
|
|
378
|
+
],
|
|
379
|
+
"synthesis_prompt": plan.synthesis_prompt,
|
|
380
|
+
},
|
|
381
|
+
indent=2,
|
|
382
|
+
)
|
|
383
|
+
else:
|
|
384
|
+
raise ValueError(f"Unknown format: {output_format}")
|